home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / cvs-1.8 / cvs-1 / cvs-1.8.1 / src / server.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-06  |  100.6 KB  |  4,643 lines

  1. #include <assert.h>
  2. #include "cvs.h"
  3. #include "watch.h"
  4. #include "edit.h"
  5. #include "fileattr.h"
  6.  
  7. #ifdef SERVER_SUPPORT
  8.  
  9. /* for select */
  10. #include <sys/types.h>
  11. #ifdef HAVE_SYS_BSDTYPES_H
  12. #include <sys/bsdtypes.h>
  13. #endif
  14. #include <sys/time.h>
  15.  
  16. #if HAVE_SYS_SELECT_H
  17. #include <sys/select.h>
  18. #endif
  19.  
  20. #if HAVE_FCNTL_H
  21. #include <fcntl.h>
  22. #endif
  23.  
  24. #ifndef O_NONBLOCK
  25. #define O_NONBLOCK O_NDELAY
  26. #endif
  27.  
  28. #ifdef AUTH_SERVER_SUPPORT
  29. /* For initgroups().  */
  30. #if HAVE_INITGROUPS
  31. #include <grp.h>
  32. #endif /* HAVE_INITGROUPS */
  33. #endif /* AUTH_SERVER_SUPPORT */
  34.  
  35.  
  36. /* Functions which the server calls.  */
  37. int add PROTO((int argc, char **argv));
  38. int admin PROTO((int argc, char **argv));
  39. int checkout PROTO((int argc, char **argv));
  40. int commit PROTO((int argc, char **argv));
  41. int diff PROTO((int argc, char **argv));
  42. int history PROTO((int argc, char **argv));
  43. int import PROTO((int argc, char **argv));
  44. int cvslog PROTO((int argc, char **argv));
  45. int patch PROTO((int argc, char **argv));
  46. int release PROTO((int argc, char **argv));
  47. int cvsremove PROTO((int argc, char **argv));
  48. int rtag PROTO((int argc, char **argv));
  49. int status PROTO((int argc, char **argv));
  50. int tag PROTO((int argc, char **argv));
  51. int update PROTO((int argc, char **argv));
  52.  
  53.  
  54. /*
  55.  * This is where we stash stuff we are going to use.  Format string
  56.  * which expects a single directory within it, starting with a slash.
  57.  */
  58. static char *server_temp_dir;
  59.  
  60. /* Nonzero if we should keep the temp directory around after we exit.  */
  61. static int dont_delete_temp;
  62.  
  63. static char no_mem_error;
  64. #define NO_MEM_ERROR (&no_mem_error)
  65.  
  66. static void server_write_entries PROTO((void));
  67.  
  68. /*
  69.  * Read a line from the stream "instream" without command line editing.
  70.  *
  71.  * Action is compatible with "readline", e.g. space for the result is
  72.  * malloc'd and should be freed by the caller.
  73.  *
  74.  * A NULL return means end of file.  A return of NO_MEM_ERROR means
  75.  * that we are out of memory.
  76.  */
  77. static char *read_line PROTO((FILE *));
  78.  
  79. static char *
  80. read_line (stream)
  81.     FILE *stream;
  82. {
  83.     int c;
  84.     char *result;
  85.     int input_index = 0;
  86.     int result_size = 80;
  87.  
  88.     fflush (stdout);
  89.     result = (char *) malloc (result_size);
  90.     if (result == NULL)
  91.     return NO_MEM_ERROR;
  92.     
  93.     while (1)
  94.     {
  95.     c = fgetc (stream);
  96.     
  97.     if (c == EOF)
  98.     {
  99.         free (result);
  100.         return NULL;
  101.     }
  102.     
  103.     if (c == '\n')
  104.         break;
  105.     
  106.     result[input_index++] = c;
  107.     while (input_index >= result_size)
  108.     {
  109.         result_size *= 2;
  110.         result = (char *) realloc (result, result_size);
  111.         if (result == NULL)
  112.         return NO_MEM_ERROR;
  113.     }
  114.     }
  115.     
  116.     result[input_index++] = '\0';
  117.     return result;
  118. }
  119.  
  120. /*
  121.  * Make directory DIR, including all intermediate directories if necessary.
  122.  * Returns 0 for success or errno code.
  123.  */
  124. static int mkdir_p PROTO((char *));
  125.  
  126. static int
  127. mkdir_p (dir)
  128.      char *dir;
  129. {
  130.     char *p;
  131.     char *q = malloc (strlen (dir) + 1);
  132.     int retval;
  133.  
  134.     if (q == NULL)
  135.     return ENOMEM;
  136.  
  137.     /*
  138.      * Skip over leading slash if present.  We won't bother to try to
  139.      * make '/'.
  140.      */
  141.     p = dir + 1;
  142.     while (1)
  143.     {
  144.     while (*p != '/' && *p != '\0')
  145.         ++p;
  146.     if (*p == '/')
  147.     {
  148.         strncpy (q, dir, p - dir);
  149.         q[p - dir] = '\0';
  150.         if (CVS_MKDIR (q, 0777) < 0)
  151.         {
  152.         if (errno != EEXIST
  153.             && (errno != EACCES || !isdir(q)))
  154.         {
  155.             retval = errno;
  156.             goto done;
  157.         }
  158.         }
  159.         ++p;
  160.     }
  161.     else
  162.     {
  163.         if (CVS_MKDIR (dir, 0777) < 0)
  164.         retval = errno;
  165.         else
  166.         retval = 0;
  167.         goto done;
  168.     }
  169.     }
  170.   done:
  171.     free (q);
  172.     return retval;
  173. }
  174.  
  175. /*
  176.  * Print the error response for error code STATUS.  The caller is
  177.  * reponsible for making sure we get back to the command loop without
  178.  * any further output occuring.
  179.  */
  180. static void
  181. print_error (status)
  182.     int status;
  183. {
  184.     char *msg;
  185.     printf ("error  ");
  186.     msg = strerror (status);
  187.     if (msg)
  188.     printf ("%s", msg);
  189.     printf ("\n");
  190. }
  191.  
  192. static int pending_error;
  193. /*
  194.  * Malloc'd text for pending error.  Each line must start with "E ".  The
  195.  * last line should not end with a newline.
  196.  */
  197. static char *pending_error_text;
  198.  
  199. /* If an error is pending, print it and return 1.  If not, return 0.  */
  200. static int
  201. print_pending_error ()
  202. {
  203.     if (pending_error_text)
  204.     {
  205.     printf ("%s\n", pending_error_text);
  206.     if (pending_error)
  207.         print_error (pending_error);
  208.     else
  209.         printf ("error  \n");
  210.     pending_error = 0;
  211.     free (pending_error_text);
  212.     pending_error_text = NULL;
  213.     return 1;
  214.     }
  215.     else if (pending_error)
  216.     {
  217.     print_error (pending_error);
  218.     pending_error = 0;
  219.     return 1;
  220.     }
  221.     else
  222.     return 0;
  223. }
  224.  
  225. /* Is an error pending?  */
  226. #define error_pending() (pending_error || pending_error_text)
  227.  
  228. int
  229. supported_response (name)
  230.      char *name;
  231. {
  232.     struct response *rs;
  233.  
  234.     for (rs = responses; rs->name != NULL; ++rs)
  235.     if (strcmp (rs->name, name) == 0)
  236.         return rs->status == rs_supported;
  237.     error (1, 0, "internal error: testing support for unknown response?");
  238.     /* NOTREACHED */
  239.     return 0;
  240. }
  241.  
  242. static void
  243. serve_valid_responses (arg)
  244.      char *arg;
  245. {
  246.     char *p = arg;
  247.     char *q;
  248.     struct response *rs;
  249.     do
  250.     {
  251.     q = strchr (p, ' ');
  252.     if (q != NULL)
  253.         *q++ = '\0';
  254.     for (rs = responses; rs->name != NULL; ++rs)
  255.     {
  256.         if (strcmp (rs->name, p) == 0)
  257.         break;
  258.     }
  259.     if (rs->name == NULL)
  260.         /*
  261.          * It is a response we have never heard of (and thus never
  262.          * will want to use).  So don't worry about it.
  263.          */
  264.         ;
  265.     else
  266.         rs->status = rs_supported;
  267.     p = q;
  268.     } while (q != NULL);
  269.     for (rs = responses; rs->name != NULL; ++rs)
  270.     {
  271.     if (rs->status == rs_essential)
  272.     {
  273.         printf ("E response `%s' not supported by client\nerror  \n",
  274.             rs->name);
  275.         exit (EXIT_FAILURE);
  276.     }
  277.     else if (rs->status == rs_optional)
  278.         rs->status = rs_not_supported;
  279.     }
  280. }
  281.  
  282. static int use_dir_and_repos = 0;
  283.  
  284. static void
  285. serve_root (arg)
  286.     char *arg;
  287. {
  288.     char *env;
  289.     extern char *CVSroot;
  290.     char path[PATH_MAX];
  291.     int save_errno;
  292.     
  293.     if (error_pending()) return;
  294.     
  295.     (void) sprintf (path, "%s/%s", arg, CVSROOTADM);
  296.     if (!isaccessible (path, R_OK | X_OK))
  297.     {
  298.     save_errno = errno;
  299.     pending_error_text = malloc (80 + strlen (path));
  300.     if (pending_error_text != NULL)
  301.         sprintf (pending_error_text, "E Cannot access %s", path);
  302.     pending_error = save_errno;
  303.     }
  304.     (void) strcat (path, "/");
  305.     (void) strcat (path, CVSROOTADM_HISTORY);
  306.     if (isfile (path) && !isaccessible (path, R_OK | W_OK))
  307.     {
  308.     save_errno = errno;
  309.     pending_error_text = malloc (80 + strlen (path));
  310.     if (pending_error_text != NULL)
  311.         sprintf (pending_error_text, "E \
  312. Sorry, you don't have read/write access to the history file %s", path);
  313.     pending_error = save_errno;
  314.     }
  315.  
  316.     CVSroot = malloc (strlen (arg) + 1);
  317.     if (CVSroot == NULL)
  318.     {
  319.     pending_error = ENOMEM;
  320.     return;
  321.     }
  322.     strcpy (CVSroot, arg);
  323. #ifdef HAVE_PUTENV
  324.     env = malloc (strlen (CVSROOT_ENV) + strlen (CVSroot) + 1 + 1);
  325.     if (env == NULL)
  326.     {
  327.     pending_error = ENOMEM;
  328.     return;
  329.     }
  330.     (void) sprintf (env, "%s=%s", CVSROOT_ENV, arg);
  331.     (void) putenv (env);
  332.     /* do not free env, as putenv has control of it */
  333. #endif
  334. }
  335.  
  336. /*
  337.  * Add as many directories to the temp directory as the client tells us it
  338.  * will use "..", so we never try to access something outside the temp
  339.  * directory via "..".
  340.  */
  341. static void
  342. serve_max_dotdot (arg)
  343.     char *arg;
  344. {
  345.     int lim = atoi (arg);
  346.     int i;
  347.     char *p;
  348.  
  349.     if (lim < 0)
  350.     return;
  351.     p = malloc (strlen (server_temp_dir) + 2 * lim + 10);
  352.     if (p == NULL)
  353.     {
  354.     pending_error = ENOMEM;
  355.     return;
  356.     }
  357.     strcpy (p, server_temp_dir);
  358.     for (i = 0; i < lim; ++i)
  359.     strcat (p, "/d");
  360.     free (server_temp_dir);
  361.     server_temp_dir = p;
  362. }
  363.  
  364. static char *dir_name;
  365.  
  366. static void
  367. dirswitch (dir, repos)
  368.     char *dir;
  369.     char *repos;
  370. {
  371.     int status;
  372.     FILE *f;
  373.  
  374.     server_write_entries ();
  375.  
  376.     if (error_pending()) return;
  377.  
  378.     if (dir_name != NULL)
  379.     free (dir_name);
  380.  
  381.     dir_name = malloc (strlen (server_temp_dir) + strlen (dir) + 40);
  382.     if (dir_name == NULL)
  383.     {
  384.     pending_error = ENOMEM;
  385.     return;
  386.     }
  387.     
  388.     strcpy (dir_name, server_temp_dir);
  389.     strcat (dir_name, "/");
  390.     strcat (dir_name, dir);
  391.  
  392.     status = mkdir_p (dir_name);    
  393.     if (status != 0
  394.     && status != EEXIST)
  395.     {
  396.     pending_error = status;
  397.     pending_error_text = malloc (80 + strlen(dir_name));
  398.     sprintf(pending_error_text, "E cannot mkdir %s", dir_name);
  399.     return;
  400.     }
  401.     if (chdir (dir_name) < 0)
  402.     {
  403.     pending_error = errno;
  404.     pending_error_text = malloc (80 + strlen(dir_name));
  405.     sprintf(pending_error_text, "E cannot change to %s", dir_name);
  406.     return;
  407.     }
  408.     /*
  409.      * This is pretty much like calling Create_Admin, but Create_Admin doesn't
  410.      * report errors in the right way for us.
  411.      */
  412.     if (CVS_MKDIR (CVSADM, 0777) < 0)
  413.     {
  414.     if (errno == EEXIST)
  415.         /* Don't create the files again.  */
  416.         return;
  417.     pending_error = errno;
  418.     return;
  419.     }
  420.     f = fopen (CVSADM_REP, "w");
  421.     if (f == NULL)
  422.     {
  423.     pending_error = errno;
  424.     return;
  425.     }
  426.     if (fprintf (f, "%s\n", repos) < 0)
  427.     {
  428.     pending_error = errno;
  429.     fclose (f);
  430.     return;
  431.     }
  432.     if (fclose (f) == EOF)
  433.     {
  434.     pending_error = errno;
  435.     return;
  436.     }
  437.     f = fopen (CVSADM_ENT, "w+");
  438.     if (f == NULL)
  439.     {
  440.     pending_error = errno;
  441.     pending_error_text = malloc (80 + strlen(CVSADM_ENT));
  442.     sprintf(pending_error_text, "E cannot open %s", CVSADM_ENT);
  443.     return;
  444.     }
  445.     if (fclose (f) == EOF)
  446.     {
  447.     pending_error = errno;
  448.     pending_error_text = malloc (80 + strlen(CVSADM_ENT));
  449.     sprintf(pending_error_text, "E cannot close %s", CVSADM_ENT);
  450.     return;
  451.     }
  452. }
  453.  
  454. static void
  455. serve_repository (arg)
  456.     char *arg;
  457. {
  458.     dirswitch (arg + 1, arg);
  459. }
  460.  
  461. static void
  462. serve_directory (arg)
  463.     char *arg;
  464. {
  465.     char *repos;
  466.     use_dir_and_repos = 1;
  467.     repos = read_line (stdin);
  468.     if (repos == NULL)
  469.     {
  470.     pending_error_text = malloc (80 + strlen (arg));
  471.     if (pending_error_text)
  472.     {
  473.         if (feof (stdin))
  474.         sprintf (pending_error_text,
  475.              "E end of file reading mode for %s", arg);
  476.         else
  477.         {
  478.         sprintf (pending_error_text,
  479.              "E error reading mode for %s", arg);
  480.         pending_error = errno;
  481.         }
  482.     }
  483.     else
  484.         pending_error = ENOMEM;
  485.     }
  486.     else if (repos == NO_MEM_ERROR)
  487.     {
  488.     pending_error = ENOMEM;
  489.     }
  490.     else
  491.     {
  492.     dirswitch (arg, repos);
  493.     free (repos);
  494.     }
  495. }
  496.  
  497. static void
  498. serve_static_directory (arg)
  499.     char *arg;
  500. {
  501.     FILE *f;
  502.     f = fopen (CVSADM_ENTSTAT, "w+");
  503.     if (f == NULL)
  504.     {
  505.     pending_error = errno;
  506.     pending_error_text = malloc (80 + strlen(CVSADM_ENTSTAT));
  507.     sprintf(pending_error_text, "E cannot open %s", CVSADM_ENTSTAT);
  508.     return;
  509.     }
  510.     if (fclose (f) == EOF)
  511.     {
  512.     pending_error = errno;
  513.     pending_error_text = malloc (80 + strlen(CVSADM_ENTSTAT));
  514.     sprintf(pending_error_text, "E cannot close %s", CVSADM_ENTSTAT);
  515.     return;
  516.     }
  517. }
  518.  
  519. static void
  520. serve_sticky (arg)
  521.     char *arg;
  522. {
  523.     FILE *f;
  524.     f = fopen (CVSADM_TAG, "w+");
  525.     if (f == NULL)
  526.     {
  527.     pending_error = errno;
  528.     pending_error_text = malloc (80 + strlen(CVSADM_TAG));
  529.     sprintf(pending_error_text, "E cannot open %s", CVSADM_TAG);
  530.     return;
  531.     }
  532.     if (fprintf (f, "%s\n", arg) < 0)
  533.     {
  534.     pending_error = errno;
  535.     pending_error_text = malloc (80 + strlen(CVSADM_TAG));
  536.     sprintf(pending_error_text, "E cannot write to %s", CVSADM_TAG);
  537.     return;
  538.     }
  539.     if (fclose (f) == EOF)
  540.     {
  541.     pending_error = errno;
  542.     pending_error_text = malloc (80 + strlen(CVSADM_TAG));
  543.     sprintf(pending_error_text, "E cannot close %s", CVSADM_TAG);
  544.     return;
  545.     }
  546. }
  547.  
  548. /*
  549.  * Read SIZE bytes from stdin, write them to FILE.
  550.  *
  551.  * Currently this isn't really used for receiving parts of a file --
  552.  * the file is still sent over in one chunk.  But if/when we get
  553.  * spiffy in-process gzip support working, perhaps the compressed
  554.  * pieces could be sent over as they're ready, if the network is fast
  555.  * enough.  Or something.
  556.  */
  557. static void
  558. receive_partial_file (size, file)
  559.      int size;
  560.      int file;
  561. {
  562.     char buf[16*1024], *bufp;
  563.     int toread, nread, nwrote;
  564.     while (size > 0)
  565.     {
  566.     toread = sizeof (buf);
  567.     if (toread > size)
  568.         toread = size;
  569.  
  570.     nread = fread (buf, 1, toread, stdin);
  571.     if (nread <= 0)
  572.     {
  573.         if (feof (stdin))
  574.         {
  575.         pending_error_text = malloc (80);
  576.         if (pending_error_text)
  577.         {
  578.             sprintf (pending_error_text,
  579.                  "E premature end of file from client");
  580.             pending_error = 0;
  581.         }
  582.         else
  583.             pending_error = ENOMEM;
  584.         }
  585.         else if (ferror (stdin))
  586.         {
  587.         pending_error_text = malloc (40);
  588.         if (pending_error_text)
  589.             sprintf (pending_error_text,
  590.                  "E error reading from client");
  591.         pending_error = errno;
  592.         }
  593.         else
  594.         {
  595.         pending_error_text = malloc (40);
  596.         if (pending_error_text)
  597.             sprintf (pending_error_text,
  598.                  "E short read from client");
  599.         pending_error = 0;
  600.         }
  601.         return;
  602.     }
  603.     size -= nread;
  604.     bufp = buf;
  605.     while (nread)
  606.     {
  607.         nwrote = write (file, bufp, nread);
  608.         if (nwrote < 0)
  609.         {
  610.         pending_error_text = malloc (40);
  611.         if (pending_error_text)
  612.             sprintf (pending_error_text, "E unable to write");
  613.         pending_error = errno;
  614.         return;
  615.         }
  616.         nread -= nwrote;
  617.         bufp += nwrote;
  618.     }
  619.     }
  620. }
  621.  
  622. /* Receive SIZE bytes, write to filename FILE.  */
  623. static void
  624. receive_file (size, file, gzipped)
  625.      int size;
  626.      char *file;
  627.      int gzipped;
  628. {
  629.     int fd;
  630.     char *arg = file;
  631.     pid_t gzip_pid = 0;
  632.     int gzip_status;
  633.  
  634.     /* Write the file.  */
  635.     fd = open (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
  636.     if (fd < 0)
  637.     {
  638.     pending_error_text = malloc (40 + strlen (arg));
  639.     if (pending_error_text)
  640.         sprintf (pending_error_text, "E cannot open %s", arg);
  641.     pending_error = errno;
  642.     return;
  643.     }
  644.  
  645.     /*
  646.      * FIXME: This doesn't do anything reasonable with gunzip's stderr, which
  647.      * means that if gunzip writes to stderr, it will cause all manner of
  648.      * protocol violations.
  649.      */
  650.     if (gzipped)
  651.     fd = filter_through_gunzip (fd, 0, &gzip_pid);
  652.  
  653.     receive_partial_file (size, fd);
  654.  
  655.     if (pending_error_text)
  656.     {
  657.     char *p = realloc (pending_error_text,
  658.                strlen (pending_error_text) + strlen (arg) + 30);
  659.     if (p)
  660.     {
  661.         pending_error_text = p;
  662.         sprintf (p + strlen (p), ", file %s", arg);
  663.     }
  664.     /* else original string is supposed to be unchanged */
  665.     }
  666.  
  667.     if (close (fd) < 0 && !error_pending ())
  668.     {
  669.     pending_error_text = malloc (40 + strlen (arg));
  670.     if (pending_error_text)
  671.         sprintf (pending_error_text, "E cannot close %s", arg);
  672.     pending_error = errno;
  673.     if (gzip_pid)
  674.         waitpid (gzip_pid, (int *) 0, 0);
  675.     return;
  676.     }
  677.  
  678.     if (gzip_pid)
  679.     {
  680.     if (waitpid (gzip_pid, &gzip_status, 0) != gzip_pid)
  681.         error (1, errno, "waiting for gunzip process %ld",
  682.            (long) gzip_pid);
  683.     else if (gzip_status != 0)
  684.         error (1, 0, "gunzip exited %d", gzip_status);
  685.     }
  686. }
  687.  
  688. static void
  689. serve_modified (arg)
  690.      char *arg;
  691. {
  692.     int size;
  693.     char *size_text;
  694.     char *mode_text;
  695.  
  696.     int gzipped = 0;
  697.  
  698.     if (error_pending ()) return;
  699.  
  700.     mode_text = read_line (stdin);
  701.     if (mode_text == NULL)
  702.     {
  703.     pending_error_text = malloc (80 + strlen (arg));
  704.     if (pending_error_text)
  705.     {
  706.         if (feof (stdin))
  707.         sprintf (pending_error_text,
  708.              "E end of file reading mode for %s", arg);
  709.         else
  710.         {
  711.         sprintf (pending_error_text,
  712.              "E error reading mode for %s", arg);
  713.         pending_error = errno;
  714.         }
  715.     }
  716.     else
  717.         pending_error = ENOMEM;
  718.     return;
  719.     } 
  720.     else if (mode_text == NO_MEM_ERROR)
  721.     {
  722.     pending_error = ENOMEM;
  723.     return;
  724.     }
  725.     size_text = read_line (stdin);
  726.     if (size_text == NULL)
  727.     {
  728.     pending_error_text = malloc (80 + strlen (arg));
  729.     if (pending_error_text)
  730.     {
  731.         if (feof (stdin))
  732.         sprintf (pending_error_text,
  733.              "E end of file reading size for %s", arg);
  734.         else
  735.         {
  736.         sprintf (pending_error_text,
  737.              "E error reading size for %s", arg);
  738.         pending_error = errno;
  739.         }
  740.     }
  741.     else
  742.         pending_error = ENOMEM;
  743.     return;
  744.     } 
  745.     else if (size_text == NO_MEM_ERROR)
  746.     {
  747.     pending_error = ENOMEM;
  748.     return;
  749.     }
  750.     if (size_text[0] == 'z')
  751.       {
  752.     gzipped = 1;
  753.     size = atoi (size_text + 1);
  754.       }
  755.     else
  756.       size = atoi (size_text);
  757.     free (size_text);
  758.  
  759.     if (size >= 0)
  760.       {
  761.     receive_file (size, arg, gzipped);
  762.     if (error_pending ()) return;
  763.       }
  764.  
  765.     {
  766.     int status = change_mode (arg, mode_text);
  767.     free (mode_text);
  768.     if (status)
  769.     {
  770.         pending_error_text = malloc (40 + strlen (arg));
  771.         if (pending_error_text)
  772.         sprintf (pending_error_text,
  773.              "E cannot change mode for %s", arg);
  774.         pending_error = status;
  775.         return;
  776.     }
  777.     }
  778. }
  779.  
  780. #endif /* SERVER_SUPPORT */
  781.  
  782. #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
  783.  
  784. int use_unchanged = 0;
  785.  
  786. #endif
  787. #ifdef SERVER_SUPPORT
  788.  
  789. static void
  790. serve_enable_unchanged (arg)
  791.      char *arg;
  792. {
  793.   use_unchanged = 1;
  794. }
  795.  
  796. static void
  797. serve_lost (arg)
  798.     char *arg;
  799. {
  800.     if (use_unchanged)
  801.     {
  802.     /* A missing file already indicates it is nonexistent.  */
  803.     return;
  804.     }
  805.     else
  806.     {
  807.     struct utimbuf ut;
  808.     int fd = open (arg, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  809.     if (fd < 0 || close (fd) < 0)
  810.     {
  811.         pending_error = errno;
  812.         pending_error_text = malloc (80 + strlen(arg));
  813.         sprintf(pending_error_text, "E cannot open %s", arg);
  814.         return;
  815.     }
  816.     /*
  817.      * Set the times to the beginning of the epoch to tell time_stamp()
  818.      * that the file was lost.
  819.      */
  820.     ut.actime = 0;
  821.     ut.modtime = 0;
  822.     if (utime (arg, &ut) < 0)
  823.     {
  824.         pending_error = errno;
  825.         pending_error_text = malloc (80 + strlen(arg));
  826.         sprintf(pending_error_text, "E cannot utime %s", arg);
  827.         return;
  828.     }
  829.     }
  830. }
  831.  
  832. struct an_entry {
  833.     struct an_entry *next;
  834.     char *entry;
  835. };
  836.  
  837. static struct an_entry *entries;
  838.  
  839. static void
  840. serve_unchanged (arg)
  841.     char *arg;
  842. {
  843.     if (error_pending ())
  844.     return;
  845.     if (!use_unchanged) 
  846.     {
  847.     /* A missing file already indicates it is unchanged.  */
  848.     return;
  849.     }
  850.     else
  851.     {
  852.     struct an_entry *p;
  853.     char *name;
  854.     char *cp;
  855.     char *timefield;
  856.  
  857.     /* Rewrite entries file to have `=' in timestamp field.  */
  858.     for (p = entries; p != NULL; p = p->next)
  859.     {
  860.         name = p->entry + 1;
  861.         cp = strchr (name, '/');
  862.         if (cp != NULL
  863.         && strlen (arg) == cp - name
  864.         && strncmp (arg, name, cp - name) == 0)
  865.         {
  866.         timefield = strchr (cp + 1, '/') + 1;
  867.         if (*timefield != '=')
  868.         {
  869.             cp = timefield + strlen (timefield);
  870.             cp[1] = '\0';
  871.             while (cp > timefield)
  872.             {
  873.             *cp = cp[-1];
  874.             --cp;
  875.             }
  876.             *timefield = '=';
  877.         }
  878.         break;
  879.         }
  880.     }
  881.     }
  882. }
  883.  
  884. static void
  885. serve_entry (arg)
  886.      char *arg;
  887. {
  888.     struct an_entry *p;
  889.     char *cp;
  890.     if (error_pending()) return;
  891.     p = (struct an_entry *) malloc (sizeof (struct an_entry));
  892.     if (p == NULL)
  893.     {
  894.     pending_error = ENOMEM;
  895.     return;
  896.     }
  897.     /* Leave space for serve_unchanged to write '=' if it wants.  */
  898.     cp = malloc (strlen (arg) + 2);
  899.     if (cp == NULL)
  900.     {
  901.     pending_error = ENOMEM;
  902.     return;
  903.     }
  904.     strcpy (cp, arg);
  905.     p->next = entries;
  906.     p->entry = cp;
  907.     entries = p;
  908. }
  909.  
  910. static void
  911. server_write_entries ()
  912. {
  913.     FILE *f;
  914.     struct an_entry *p;
  915.     struct an_entry *q;
  916.  
  917.     if (entries == NULL)
  918.     return;
  919.  
  920.     f = NULL;
  921.     /* Note that we free all the entries regardless of errors.  */
  922.     if (!error_pending ())
  923.     {
  924.     f = fopen (CVSADM_ENT, "w");
  925.     if (f == NULL)
  926.     {
  927.         pending_error = errno;
  928.         pending_error_text = malloc (80 + strlen(CVSADM_ENT));
  929.         sprintf(pending_error_text, "E cannot open %s", CVSADM_ENT);
  930.     }
  931.     }
  932.     for (p = entries; p != NULL;)
  933.     {
  934.     if (!error_pending ())
  935.     {
  936.         if (fprintf (f, "%s\n", p->entry) < 0)
  937.         {
  938.         pending_error = errno;
  939.         pending_error_text = malloc (80 + strlen(CVSADM_ENT));
  940.         sprintf(pending_error_text, "E cannot write to %s", CVSADM_ENT);
  941.         }
  942.     }
  943.     free (p->entry);
  944.     q = p->next;
  945.     free (p);
  946.     p = q;
  947.     }
  948.     entries = NULL;
  949.     if (f != NULL && fclose (f) == EOF && !error_pending ())
  950.     {
  951.     pending_error = errno;
  952.     pending_error_text = malloc (80 + strlen(CVSADM_ENT));
  953.     sprintf(pending_error_text, "E cannot close %s", CVSADM_ENT);
  954.     }
  955. }
  956.  
  957. struct notify_note {
  958.     /* Directory in which this notification happens.  malloc'd*/
  959.     char *dir;
  960.  
  961.     /* malloc'd.  */
  962.     char *filename;
  963.  
  964.     /* The following three all in one malloc'd block, pointed to by TYPE.
  965.        Each '\0' terminated.  */
  966.     /* "E" or "U".  */
  967.     char *type;
  968.     /* time+host+dir */
  969.     char *val;
  970.     char *watches;
  971.  
  972.     struct notify_note *next;
  973. };
  974.  
  975. static struct notify_note *notify_list;
  976. /* Used while building list, to point to the last node that already exists.  */
  977. static struct notify_note *last_node;
  978.  
  979. static void serve_notify PROTO ((char *));
  980.  
  981. static void
  982. serve_notify (arg)
  983.     char *arg;
  984. {
  985.     struct notify_note *new;
  986.     char *data;
  987.  
  988.     if (error_pending ()) return;
  989.  
  990.     new = (struct notify_note *) malloc (sizeof (struct notify_note));
  991.     if (new == NULL)
  992.     {
  993.     pending_error = ENOMEM;
  994.     return;
  995.     }
  996.     if (dir_name == NULL)
  997.     goto error;
  998.     new->dir = malloc (strlen (dir_name) + 1);
  999.     if (new->dir == NULL)
  1000.     {
  1001.     pending_error = ENOMEM;
  1002.     return;
  1003.     }
  1004.     strcpy (new->dir, dir_name);
  1005.     new->filename = malloc (strlen (arg) + 1);
  1006.     if (new->filename == NULL)
  1007.     {
  1008.     pending_error = ENOMEM;
  1009.     return;
  1010.     }
  1011.     strcpy (new->filename, arg);
  1012.  
  1013.     data = read_line (stdin);
  1014.     if (data == NULL)
  1015.     {
  1016.     pending_error_text = malloc (80 + strlen (arg));
  1017.     if (pending_error_text)
  1018.     {
  1019.         if (feof (stdin))
  1020.         sprintf (pending_error_text,
  1021.              "E end of file reading mode for %s", arg);
  1022.         else
  1023.         {
  1024.         sprintf (pending_error_text,
  1025.              "E error reading mode for %s", arg);
  1026.         pending_error = errno;
  1027.         }
  1028.     }
  1029.     else
  1030.         pending_error = ENOMEM;
  1031.     }
  1032.     else if (data == NO_MEM_ERROR)
  1033.     {
  1034.     pending_error = ENOMEM;
  1035.     }
  1036.     else
  1037.     {
  1038.     char *cp;
  1039.  
  1040.     new->type = data;
  1041.     if (data[1] != '\t')
  1042.         goto error;
  1043.     data[1] = '\0';
  1044.     cp = data + 2;
  1045.     new->val = cp;
  1046.     cp = strchr (cp, '\t');
  1047.     if (cp == NULL)
  1048.         goto error;
  1049.     *cp++ = '+';
  1050.     cp = strchr (cp, '\t');
  1051.     if (cp == NULL)
  1052.         goto error;
  1053.     *cp++ = '+';
  1054.     cp = strchr (cp, '\t');
  1055.     if (cp == NULL)
  1056.         goto error;
  1057.     *cp++ = '\0';
  1058.     new->watches = cp;
  1059.     /* If there is another tab, ignore everything after it,
  1060.        for future expansion.  */
  1061.     cp = strchr (cp, '\t');
  1062.     if (cp != NULL)
  1063.     {
  1064.         *cp = '\0';
  1065.     }
  1066.  
  1067.     new->next = NULL;
  1068.  
  1069.     if (last_node == NULL)
  1070.     {
  1071.         notify_list = new;
  1072.     }
  1073.     else
  1074.         last_node->next = new;
  1075.     last_node = new;
  1076.     }
  1077.     return;
  1078.   error:
  1079.     pending_error_text = malloc (40);
  1080.     if (pending_error_text)
  1081.     strcpy (pending_error_text,
  1082.         "E Protocol error; misformed Notify request");
  1083.     pending_error = 0;
  1084.     return;
  1085. }
  1086.  
  1087. /* Process all the Notify requests that we have stored up.  Returns 0
  1088.    if successful, if not prints error message (via error()) and
  1089.    returns negative value.  */
  1090. static int
  1091. server_notify ()
  1092. {
  1093.     struct notify_note *p;
  1094.     char *repos;
  1095.     List *list;
  1096.     Node *node;
  1097.     int status;
  1098.  
  1099.     while (notify_list != NULL)
  1100.     {
  1101.     if (chdir (notify_list->dir) < 0)
  1102.     {
  1103.         error (0, errno, "cannot change to %s", notify_list->dir);
  1104.         return -1;
  1105.     }
  1106.     repos = Name_Repository (NULL, NULL);
  1107.  
  1108.     /* Now writelock.  */
  1109.     list = getlist ();
  1110.     node = getnode ();
  1111.     node->type = LOCK;
  1112.     node->key = xstrdup (repos);
  1113.     status = addnode (list, node);
  1114.     assert (status == 0);
  1115.     Writer_Lock (list);
  1116.  
  1117.     fileattr_startdir (repos);
  1118.  
  1119.     notify_do (*notify_list->type, notify_list->filename, getcaller(),
  1120.            notify_list->val, notify_list->watches, repos);
  1121.  
  1122.     printf ("Notified ");
  1123.     if (use_dir_and_repos)
  1124.     {
  1125.         char *dir = notify_list->dir + strlen (server_temp_dir) + 1;
  1126.         if (dir[0] == '\0')
  1127.         fputs (".", stdout);
  1128.         else
  1129.         fputs (dir, stdout);
  1130.         fputs ("/\n", stdout);
  1131.     }
  1132.     fputs (repos, stdout);
  1133.     fputs ("/", stdout);
  1134.     fputs (notify_list->filename, stdout);
  1135.     fputs ("\n", stdout);
  1136.  
  1137.     p = notify_list->next;
  1138.     free (notify_list->filename);
  1139.     free (notify_list->dir);
  1140.     free (notify_list->type);
  1141.     free (notify_list);
  1142.     notify_list = p;
  1143.  
  1144.     fileattr_write ();
  1145.     fileattr_free ();
  1146.  
  1147.     /* Remove the writelock.  */
  1148.     Lock_Cleanup ();
  1149.     dellist (&list);
  1150.     }
  1151.     /* do_cvs_command writes to stdout via write(), not stdio, so better
  1152.        flush out the buffer.  */
  1153.     fflush (stdout);
  1154.     return 0;
  1155. }
  1156.  
  1157. static int argument_count;
  1158. static char **argument_vector;
  1159. static int argument_vector_size;
  1160.  
  1161. static void
  1162. serve_argument (arg)
  1163.      char *arg;
  1164. {
  1165.     char *p;
  1166.     
  1167.     if (error_pending()) return;
  1168.     
  1169.     if (argument_vector_size <= argument_count)
  1170.     {
  1171.     argument_vector_size *= 2;
  1172.     argument_vector =
  1173.         (char **) realloc ((char *)argument_vector,
  1174.                    argument_vector_size * sizeof (char *));
  1175.     if (argument_vector == NULL)
  1176.     {
  1177.         pending_error = ENOMEM;
  1178.         return;
  1179.     }
  1180.     }
  1181.     p = malloc (strlen (arg) + 1);
  1182.     if (p == NULL)
  1183.     {
  1184.     pending_error = ENOMEM;
  1185.     return;
  1186.     }
  1187.     strcpy (p, arg);
  1188.     argument_vector[argument_count++] = p;
  1189. }
  1190.  
  1191. static void
  1192. serve_argumentx (arg)
  1193.      char *arg;
  1194. {
  1195.     char *p;
  1196.     
  1197.     if (error_pending()) return;
  1198.     
  1199.     p = argument_vector[argument_count - 1];
  1200.     p = realloc (p, strlen (p) + 1 + strlen (arg) + 1);
  1201.     if (p == NULL)
  1202.     {
  1203.     pending_error = ENOMEM;
  1204.     return;
  1205.     }
  1206.     strcat (p, "\n");
  1207.     strcat (p, arg);
  1208.     argument_vector[argument_count - 1] = p;
  1209. }
  1210.  
  1211. static void
  1212. serve_global_option (arg)
  1213.     char *arg;
  1214. {
  1215.     if (arg[0] != '-' || arg[1] == '\0' || arg[2] != '\0')
  1216.     {
  1217.     error_return:
  1218.     pending_error_text = malloc (strlen (arg) + 80);
  1219.     sprintf (pending_error_text, "E Protocol error: bad global option %s",
  1220.          arg);
  1221.     return;
  1222.     }
  1223.     switch (arg[1])
  1224.     {
  1225.     case 'n':
  1226.         noexec = 1;
  1227.         break;
  1228.     case 'q':
  1229.         quiet = 1;
  1230.         break;
  1231.     case 'r':
  1232.         cvswrite = 0;
  1233.         break;
  1234.     case 'Q':
  1235.         really_quiet = 1;
  1236.         break;
  1237.     case 'l':
  1238.         logoff = 1;
  1239.         break;
  1240.     case 't':
  1241.         trace = 1;
  1242.         break;
  1243.     default:
  1244.         goto error_return;
  1245.     }
  1246. }
  1247.  
  1248. static void
  1249. serve_set (arg)
  1250.     char *arg;
  1251. {
  1252.     /* FIXME: This sends errors immediately (I think); they should be
  1253.        put into pending_error.  */
  1254.     variable_set (arg);
  1255. }
  1256.  
  1257. /*
  1258.  * We must read data from a child process and send it across the
  1259.  * network.  We do not want to block on writing to the network, so we
  1260.  * store the data from the child process in memory.  A BUFFER
  1261.  * structure holds the status of one communication, and uses a linked
  1262.  * list of buffer_data structures to hold data.
  1263.  */
  1264.  
  1265. struct buffer
  1266. {
  1267.     /* Data.  */
  1268.     struct buffer_data *data;
  1269.  
  1270.     /* Last buffer on data chain.  */
  1271.     struct buffer_data *last;
  1272.  
  1273.     /* File descriptor to write to or read from.  */
  1274.     int fd;
  1275.  
  1276.     /* Nonzero if this is an output buffer (sanity check).  */
  1277.     int output;
  1278.  
  1279.     /* Nonzero if the file descriptor is in nonblocking mode.  */
  1280.     int nonblocking;
  1281.  
  1282.     /* Function to call if we can't allocate memory.  */
  1283.     void (*memory_error) PROTO((struct buffer *));
  1284. };
  1285.  
  1286. /* Data is stored in lists of these structures.  */
  1287.  
  1288. struct buffer_data
  1289. {
  1290.     /* Next buffer in linked list.  */
  1291.     struct buffer_data *next;
  1292.  
  1293.     /*
  1294.      * A pointer into the data area pointed to by the text field.  This
  1295.      * is where to find data that has not yet been written out.
  1296.      */
  1297.     char *bufp;
  1298.  
  1299.     /* The number of data bytes found at BUFP.  */
  1300.     int size;
  1301.  
  1302.     /*
  1303.      * Actual buffer.  This never changes after the structure is
  1304.      * allocated.  The buffer is BUFFER_DATA_SIZE bytes.
  1305.      */
  1306.     char *text;
  1307. };
  1308.  
  1309. /* The size we allocate for each buffer_data structure.  */
  1310. #define BUFFER_DATA_SIZE (4096)
  1311.  
  1312. #ifdef SERVER_FLOWCONTROL
  1313. /* The maximum we'll queue to the remote client before blocking.  */
  1314. # ifndef SERVER_HI_WATER
  1315. #  define SERVER_HI_WATER (2 * 1024 * 1024)
  1316. # endif /* SERVER_HI_WATER */
  1317. /* When the buffer drops to this, we restart the child */
  1318. # ifndef SERVER_LO_WATER
  1319. #  define SERVER_LO_WATER (1 * 1024 * 1024)
  1320. # endif /* SERVER_LO_WATER */
  1321. #endif /* SERVER_FLOWCONTROL */
  1322.  
  1323. /* Linked list of available buffer_data structures.  */
  1324. static struct buffer_data *free_buffer_data;
  1325.  
  1326. static void allocate_buffer_datas PROTO((void));
  1327. static inline struct buffer_data *get_buffer_data PROTO((void));
  1328. static int buf_empty_p PROTO((struct buffer *));
  1329. static void buf_output PROTO((struct buffer *, const char *, int));
  1330. static void buf_output0 PROTO((struct buffer *, const char *));
  1331. static inline void buf_append_char PROTO((struct buffer *, int));
  1332. static int buf_send_output PROTO((struct buffer *));
  1333. static int set_nonblock PROTO((struct buffer *));
  1334. static int set_block PROTO((struct buffer *));
  1335. static int buf_send_counted PROTO((struct buffer *));
  1336. static inline void buf_append_data PROTO((struct buffer *,
  1337.                      struct buffer_data *,
  1338.                      struct buffer_data *));
  1339. static int buf_read_file PROTO((FILE *, long, struct buffer_data **,
  1340.                   struct buffer_data **));
  1341. static int buf_input_data PROTO((struct buffer *, int *));
  1342. static void buf_copy_lines PROTO((struct buffer *, struct buffer *, int));
  1343. static int buf_copy_counted PROTO((struct buffer *, struct buffer *));
  1344.  
  1345. #ifdef SERVER_FLOWCONTROL
  1346. static int buf_count_mem PROTO((struct buffer *));
  1347. static int set_nonblock_fd PROTO((int));
  1348. #endif /* SERVER_FLOWCONTROL */
  1349.  
  1350. /* Allocate more buffer_data structures.  */
  1351.  
  1352. static void
  1353. allocate_buffer_datas ()
  1354. {
  1355.     struct buffer_data *alc;
  1356.     char *space;
  1357.     int i;
  1358.  
  1359.     /* Allocate buffer_data structures in blocks of 16.  */
  1360. #define ALLOC_COUNT (16)
  1361.  
  1362.     alc = ((struct buffer_data *)
  1363.        malloc (ALLOC_COUNT * sizeof (struct buffer_data)));
  1364.     space = (char *) valloc (ALLOC_COUNT * BUFFER_DATA_SIZE);
  1365.     if (alc == NULL || space == NULL)
  1366.     return;
  1367.     for (i = 0; i < ALLOC_COUNT; i++, alc++, space += BUFFER_DATA_SIZE)
  1368.     {
  1369.     alc->next = free_buffer_data;
  1370.     free_buffer_data = alc;
  1371.     alc->text = space;
  1372.     }      
  1373. }
  1374.  
  1375. /* Get a new buffer_data structure.  */
  1376.  
  1377. static inline struct buffer_data *
  1378. get_buffer_data ()
  1379. {
  1380.     struct buffer_data *ret;
  1381.  
  1382.     if (free_buffer_data == NULL)
  1383.     {
  1384.     allocate_buffer_datas ();
  1385.     if (free_buffer_data == NULL)
  1386.         return NULL;
  1387.     }
  1388.  
  1389.     ret = free_buffer_data;
  1390.     free_buffer_data = ret->next;
  1391.     return ret;
  1392. }
  1393.  
  1394. /* See whether a buffer is empty.  */
  1395.  
  1396. static int
  1397. buf_empty_p (buf)
  1398.     struct buffer *buf;
  1399. {
  1400.     struct buffer_data *data;
  1401.  
  1402.     for (data = buf->data; data != NULL; data = data->next)
  1403.     if (data->size > 0)
  1404.         return 0;
  1405.     return 1;
  1406. }
  1407.  
  1408. #ifdef SERVER_FLOWCONTROL
  1409. /*
  1410.  * Count how much data is stored in the buffer..
  1411.  * Note that each buffer is a malloc'ed chunk BUFFER_DATA_SIZE.
  1412.  */
  1413.  
  1414. static int
  1415. buf_count_mem (buf)
  1416.     struct buffer *buf;
  1417. {
  1418.     struct buffer_data *data;
  1419.     int mem = 0;
  1420.  
  1421.     for (data = buf->data; data != NULL; data = data->next)
  1422.     mem += BUFFER_DATA_SIZE;
  1423.  
  1424.     return mem;
  1425. }
  1426. #endif /* SERVER_FLOWCONTROL */
  1427.  
  1428. /* Add data DATA of length LEN to BUF.  */
  1429.  
  1430. static void
  1431. buf_output (buf, data, len)
  1432.     struct buffer *buf;
  1433.     const char *data;
  1434.     int len;
  1435. {
  1436.     if (buf->data != NULL
  1437.     && (((buf->last->text + BUFFER_DATA_SIZE)
  1438.          - (buf->last->bufp + buf->last->size))
  1439.         >= len))
  1440.     {
  1441.     memcpy (buf->last->bufp + buf->last->size, data, len);
  1442.     buf->last->size += len;
  1443.     return;
  1444.     }
  1445.  
  1446.     while (1)
  1447.     {
  1448.     struct buffer_data *newdata;
  1449.  
  1450.     newdata = get_buffer_data ();
  1451.     if (newdata == NULL)
  1452.     {
  1453.         (*buf->memory_error) (buf);
  1454.         return;
  1455.     }
  1456.  
  1457.     if (buf->data == NULL)
  1458.         buf->data = newdata;
  1459.     else
  1460.         buf->last->next = newdata;
  1461.     newdata->next = NULL;
  1462.     buf->last = newdata;
  1463.  
  1464.     newdata->bufp = newdata->text;
  1465.  
  1466.     if (len <= BUFFER_DATA_SIZE)
  1467.     {
  1468.         newdata->size = len;
  1469.         memcpy (newdata->text, data, len);
  1470.         return;
  1471.     }
  1472.  
  1473.     newdata->size = BUFFER_DATA_SIZE;
  1474.     memcpy (newdata->text, data, BUFFER_DATA_SIZE);
  1475.  
  1476.     data += BUFFER_DATA_SIZE;
  1477.     len -= BUFFER_DATA_SIZE;
  1478.     }
  1479.  
  1480.     /*NOTREACHED*/
  1481. }
  1482.  
  1483. /* Add a '\0' terminated string to BUF.  */
  1484.  
  1485. static void
  1486. buf_output0 (buf, string)
  1487.     struct buffer *buf;
  1488.     const char *string;
  1489. {
  1490.     buf_output (buf, string, strlen (string));
  1491. }
  1492.  
  1493. /* Add a single character to BUF.  */
  1494.  
  1495. static inline void
  1496. buf_append_char (buf, ch)
  1497.     struct buffer *buf;
  1498.     int ch;
  1499. {
  1500.     if (buf->data != NULL
  1501.     && (buf->last->text + BUFFER_DATA_SIZE
  1502.         != buf->last->bufp + buf->last->size))
  1503.     {
  1504.     *(buf->last->bufp + buf->last->size) = ch;
  1505.     ++buf->last->size;
  1506.     }
  1507.     else
  1508.     {
  1509.     char b;
  1510.  
  1511.     b = ch;
  1512.     buf_output (buf, &b, 1);
  1513.     }
  1514. }
  1515.  
  1516. /*
  1517.  * Send all the output we've been saving up.  Returns 0 for success or
  1518.  * errno code.  If the buffer has been set to be nonblocking, this
  1519.  * will just write until the write would block.
  1520.  */
  1521.  
  1522. static int
  1523. buf_send_output (buf)
  1524.      struct buffer *buf;
  1525. {
  1526.     if (! buf->output)
  1527.     abort ();
  1528.  
  1529.     while (buf->data != NULL)
  1530.     {
  1531.     struct buffer_data *data;
  1532.  
  1533.     data = buf->data;
  1534.     while (data->size > 0)
  1535.     {
  1536.         int nbytes;
  1537.  
  1538.         nbytes = write (buf->fd, data->bufp, data->size);
  1539.         if (nbytes <= 0)
  1540.         {
  1541.         int status;
  1542.  
  1543.         if (buf->nonblocking
  1544.             && (nbytes == 0
  1545. #ifdef EWOULDBLOCK
  1546.             || errno == EWOULDBLOCK
  1547. #endif
  1548.             || errno == EAGAIN))
  1549.         {
  1550.             /*
  1551.              * A nonblocking write failed to write any data.
  1552.              * Just return.
  1553.              */
  1554.             return 0;
  1555.         }
  1556.  
  1557.         /*
  1558.          * An error, or EOF.  Throw away all the data and
  1559.          * return.
  1560.          */
  1561.         if (nbytes == 0)
  1562.             status = EIO;
  1563.         else
  1564.             status = errno;
  1565.  
  1566.         buf->last->next = free_buffer_data;
  1567.         free_buffer_data = buf->data;
  1568.         buf->data = NULL;
  1569.         buf->last = NULL;
  1570.  
  1571.         return status;
  1572.         }
  1573.  
  1574.         data->size -= nbytes;
  1575.         data->bufp += nbytes;
  1576.     }
  1577.  
  1578.     buf->data = data->next;
  1579.     data->next = free_buffer_data;
  1580.     free_buffer_data = data;
  1581.     }
  1582.  
  1583.     buf->last = NULL;
  1584.  
  1585.     return 0;
  1586. }
  1587.  
  1588. #ifdef SERVER_FLOWCONTROL
  1589. /*
  1590.  * Set buffer BUF to non-blocking I/O.  Returns 0 for success or errno
  1591.  * code.
  1592.  */
  1593.  
  1594. static int
  1595. set_nonblock_fd (fd)
  1596.      int fd;
  1597. {
  1598.     int flags;
  1599.  
  1600.     flags = fcntl (fd, F_GETFL, 0);
  1601.     if (flags < 0)
  1602.     return errno;
  1603.     if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0)
  1604.     return errno;
  1605.     return 0;
  1606. }
  1607. #endif /* SERVER_FLOWCONTROL */
  1608.  
  1609. static int
  1610. set_nonblock (buf)
  1611.      struct buffer *buf;
  1612. {
  1613.     int flags;
  1614.  
  1615.     if (buf->nonblocking)
  1616.     return 0;
  1617.     flags = fcntl (buf->fd, F_GETFL, 0);
  1618.     if (flags < 0)
  1619.     return errno;
  1620.     if (fcntl (buf->fd, F_SETFL, flags | O_NONBLOCK) < 0)
  1621.     return errno;
  1622.     buf->nonblocking = 1;
  1623.     return 0;
  1624. }
  1625.  
  1626. /*
  1627.  * Set buffer BUF to blocking I/O.  Returns 0 for success or errno
  1628.  * code.
  1629.  */
  1630.  
  1631. static int
  1632. set_block (buf)
  1633.      struct buffer *buf;
  1634. {
  1635.     int flags;
  1636.  
  1637.     if (! buf->nonblocking)
  1638.     return 0;
  1639.     flags = fcntl (buf->fd, F_GETFL, 0);
  1640.     if (flags < 0)
  1641.     return errno;
  1642.     if (fcntl (buf->fd, F_SETFL, flags & ~O_NONBLOCK) < 0)
  1643.     return errno;
  1644.     buf->nonblocking = 0;
  1645.     return 0;
  1646. }
  1647.  
  1648. /*
  1649.  * Send a character count and some output.  Returns errno code or 0 for
  1650.  * success.
  1651.  *
  1652.  * Sending the count in binary is OK since this is only used on a pipe
  1653.  * within the same system.
  1654.  */
  1655.  
  1656. static int
  1657. buf_send_counted (buf)
  1658.      struct buffer *buf;
  1659. {
  1660.     int size;
  1661.     struct buffer_data *data;
  1662.  
  1663.     if (! buf->output)
  1664.     abort ();
  1665.  
  1666.     size = 0;
  1667.     for (data = buf->data; data != NULL; data = data->next)
  1668.     size += data->size;
  1669.  
  1670.     data = get_buffer_data ();
  1671.     if (data == NULL)
  1672.     {
  1673.     (*buf->memory_error) (buf);
  1674.     return ENOMEM;
  1675.     }
  1676.  
  1677.     data->next = buf->data;
  1678.     buf->data = data;
  1679.     if (buf->last == NULL)
  1680.     buf->last = data;
  1681.  
  1682.     data->bufp = data->text;
  1683.     data->size = sizeof (int);
  1684.  
  1685.     *((int *) data->text) = size;
  1686.  
  1687.     return buf_send_output (buf);
  1688. }
  1689.  
  1690. /* Append a list of buffer_data structures to an buffer.  */
  1691.  
  1692. static inline void
  1693. buf_append_data (buf, data, last)
  1694.      struct buffer *buf;
  1695.      struct buffer_data *data;
  1696.      struct buffer_data *last;
  1697. {
  1698.     if (data != NULL)
  1699.     {
  1700.     if (buf->data == NULL)
  1701.         buf->data = data;
  1702.     else
  1703.         buf->last->next = data;
  1704.     buf->last = last;
  1705.     }
  1706. }
  1707.  
  1708. /*
  1709.  * Copy the contents of file F into buffer_data structures.  We can't
  1710.  * copy directly into an buffer, because we want to handle failure and
  1711.  * succeess differently.  Returns 0 on success, or -2 if out of
  1712.  * memory, or a status code on error.  Since the caller happens to
  1713.  * know the size of the file, it is passed in as SIZE.  On success,
  1714.  * this function sets *RETP and *LASTP, which may be passed to
  1715.  * buf_append_data.
  1716.  */
  1717.  
  1718. static int
  1719. buf_read_file (f, size, retp, lastp)
  1720.     FILE *f;
  1721.     long size;
  1722.     struct buffer_data **retp;
  1723.     struct buffer_data **lastp;
  1724. {
  1725.     int status;
  1726.  
  1727.     *retp = NULL;
  1728.     *lastp = NULL;
  1729.  
  1730.     while (size > 0)
  1731.     {
  1732.     struct buffer_data *data;
  1733.     int get;
  1734.  
  1735.     data = get_buffer_data ();
  1736.     if (data == NULL)
  1737.     {
  1738.         status = -2;
  1739.         goto error_return;
  1740.     }
  1741.  
  1742.     if (*retp == NULL)
  1743.         *retp = data;
  1744.     else
  1745.         (*lastp)->next = data;
  1746.     data->next = NULL;
  1747.     *lastp = data;
  1748.  
  1749.     data->bufp = data->text;
  1750.     data->size = 0;
  1751.  
  1752.     if (size > BUFFER_DATA_SIZE)
  1753.         get = BUFFER_DATA_SIZE;
  1754.     else
  1755.         get = size;
  1756.  
  1757.     errno = EIO;
  1758.     if (fread (data->text, get, 1, f) != 1)
  1759.     {
  1760.         status = errno;
  1761.         goto error_return;
  1762.     }
  1763.  
  1764.     data->size += get;
  1765.     size -= get;
  1766.     }
  1767.  
  1768.     return 0;
  1769.  
  1770.   error_return:
  1771.     if (*retp != NULL)
  1772.     {
  1773.     (*lastp)->next = free_buffer_data;
  1774.     free_buffer_data = *retp;
  1775.     }
  1776.     return status;
  1777. }
  1778.  
  1779. static int
  1780. buf_read_file_to_eof (f, retp, lastp)
  1781.      FILE *f;
  1782.      struct buffer_data **retp;
  1783.      struct buffer_data **lastp;
  1784. {
  1785.     int status;
  1786.  
  1787.     *retp = NULL;
  1788.     *lastp = NULL;
  1789.  
  1790.     while (!feof (f))
  1791.     {
  1792.     struct buffer_data *data;
  1793.     int get, nread;
  1794.  
  1795.     data = get_buffer_data ();
  1796.     if (data == NULL)
  1797.     {
  1798.         status = -2;
  1799.         goto error_return;
  1800.     }
  1801.  
  1802.     if (*retp == NULL)
  1803.         *retp = data;
  1804.     else
  1805.         (*lastp)->next = data;
  1806.     data->next = NULL;
  1807.     *lastp = data;
  1808.  
  1809.     data->bufp = data->text;
  1810.     data->size = 0;
  1811.  
  1812.     get = BUFFER_DATA_SIZE;
  1813.  
  1814.     errno = EIO;
  1815.     nread = fread (data->text, 1, get, f);
  1816.     if (nread == 0 && !feof (f))
  1817.     {
  1818.         status = errno;
  1819.         goto error_return;
  1820.     }
  1821.  
  1822.     data->size = nread;
  1823.     }
  1824.  
  1825.     return 0;
  1826.  
  1827.   error_return:
  1828.     if (*retp != NULL)
  1829.     {
  1830.     (*lastp)->next = free_buffer_data;
  1831.     free_buffer_data = *retp;
  1832.     }
  1833.     return status;
  1834. }
  1835.  
  1836. static int
  1837. buf_chain_length (buf)
  1838.      struct buffer_data *buf;
  1839. {
  1840.     int size = 0;
  1841.     while (buf)
  1842.     {
  1843.     size += buf->size;
  1844.     buf = buf->next;
  1845.     }
  1846.     return size;
  1847. }
  1848.  
  1849. /*
  1850.  * Read an arbitrary amount of data from a file descriptor into an
  1851.  * input buffer.  The file descriptor will be in nonblocking mode, and
  1852.  * we just grab what we can.  Return 0 on success, or -1 on end of
  1853.  * file, or -2 if out of memory, or an error code.  If COUNTP is not
  1854.  * NULL, *COUNTP is set to the number of bytes read.
  1855.  */
  1856.  
  1857. static int
  1858. buf_input_data (buf, countp)
  1859.      struct buffer *buf;
  1860.      int *countp;
  1861. {
  1862.     if (buf->output)
  1863.     abort ();
  1864.  
  1865.     if (countp != NULL)
  1866.     *countp = 0;
  1867.  
  1868.     while (1)
  1869.     {
  1870.     int get;
  1871.     int nbytes;
  1872.  
  1873.     if (buf->data == NULL
  1874.         || (buf->last->bufp + buf->last->size
  1875.         == buf->last->text + BUFFER_DATA_SIZE))
  1876.     {
  1877.         struct buffer_data *data;
  1878.  
  1879.         data = get_buffer_data ();
  1880.         if (data == NULL)
  1881.         {
  1882.         (*buf->memory_error) (buf);
  1883.         return -2;
  1884.         }
  1885.  
  1886.         if (buf->data == NULL)
  1887.         buf->data = data;
  1888.         else
  1889.         buf->last->next = data;
  1890.         data->next = NULL;
  1891.         buf->last = data;
  1892.  
  1893.         data->bufp = data->text;
  1894.         data->size = 0;
  1895.     }
  1896.  
  1897.     get = ((buf->last->text + BUFFER_DATA_SIZE)
  1898.            - (buf->last->bufp + buf->last->size));
  1899.     nbytes = read (buf->fd, buf->last->bufp + buf->last->size, get);
  1900.     if (nbytes <= 0)
  1901.     {
  1902.         if (nbytes == 0)
  1903.         {
  1904.         /*
  1905.          * This assumes that we are using POSIX or BSD style
  1906.          * nonblocking I/O.  On System V we will get a zero
  1907.          * return if there is no data, even when not at EOF.
  1908.          */
  1909.         return -1;
  1910.         }
  1911.  
  1912.         if (errno == EAGAIN
  1913. #ifdef EWOULDBLOCK
  1914.         || errno == EWOULDBLOCK
  1915. #endif
  1916.         )
  1917.           return 0;
  1918.  
  1919.         return errno;
  1920.     }
  1921.  
  1922.     buf->last->size += nbytes;
  1923.     if (countp != NULL)
  1924.         *countp += nbytes;
  1925.     }
  1926.  
  1927.     /*NOTREACHED*/
  1928. }
  1929.  
  1930. /*
  1931.  * Copy lines from an input buffer to an output buffer.  This copies
  1932.  * all complete lines (characters up to a newline) from INBUF to
  1933.  * OUTBUF.  Each line in OUTBUF is preceded by the character COMMAND
  1934.  * and a space.
  1935.  */
  1936.  
  1937. static void
  1938. buf_copy_lines (outbuf, inbuf, command)
  1939.      struct buffer *outbuf;
  1940.      struct buffer *inbuf;
  1941.      int command;
  1942. {
  1943.     if (! outbuf->output || inbuf->output)
  1944.     abort ();
  1945.  
  1946.     while (1)
  1947.     {
  1948.     struct buffer_data *data;
  1949.     struct buffer_data *nldata;
  1950.     char *nl;
  1951.     int len;
  1952.  
  1953.     /* See if there is a newline in INBUF.  */
  1954.     nldata = NULL;
  1955.     nl = NULL;
  1956.     for (data = inbuf->data; data != NULL; data = data->next)
  1957.     {
  1958.         nl = memchr (data->bufp, '\n', data->size);
  1959.         if (nl != NULL)
  1960.         {
  1961.         nldata = data;
  1962.         break;
  1963.         }
  1964.     }
  1965.  
  1966.     if (nldata == NULL)
  1967.     {
  1968.         /* There are no more lines in INBUF.  */
  1969.         return;
  1970.     }
  1971.  
  1972.     /* Put in the command.  */
  1973.     buf_append_char (outbuf, command);
  1974.     buf_append_char (outbuf, ' ');
  1975.  
  1976.     if (inbuf->data != nldata)
  1977.     {
  1978.         /*
  1979.          * Simply move over all the buffers up to the one containing
  1980.          * the newline.
  1981.          */
  1982.         for (data = inbuf->data; data->next != nldata; data = data->next)
  1983.         ;
  1984.         data->next = NULL;
  1985.         buf_append_data (outbuf, inbuf->data, data);
  1986.         inbuf->data = nldata;
  1987.     }
  1988.  
  1989.     /*
  1990.      * If the newline is at the very end of the buffer, just move
  1991.      * the buffer onto OUTBUF.  Otherwise we must copy the data.
  1992.      */
  1993.     len = nl + 1 - nldata->bufp;
  1994.     if (len == nldata->size)
  1995.     {
  1996.         inbuf->data = nldata->next;
  1997.         if (inbuf->data == NULL)
  1998.         inbuf->last = NULL;
  1999.  
  2000.         nldata->next = NULL;
  2001.         buf_append_data (outbuf, nldata, nldata);
  2002.     }
  2003.     else
  2004.     {
  2005.         buf_output (outbuf, nldata->bufp, len);
  2006.         nldata->bufp += len;
  2007.         nldata->size -= len;
  2008.     }
  2009.     }
  2010. }
  2011.  
  2012. /*
  2013.  * Copy counted data from one buffer to another.  The count is an
  2014.  * integer, host size, host byte order (it is only used across a
  2015.  * pipe).  If there is enough data, it should be moved over.  If there
  2016.  * is not enough data, it should remain on the original buffer.  This
  2017.  * returns the number of bytes it needs to see in order to actually
  2018.  * copy something over.
  2019.  */
  2020.  
  2021. static int
  2022. buf_copy_counted (outbuf, inbuf)
  2023.      struct buffer *outbuf;
  2024.      struct buffer *inbuf;
  2025. {
  2026.     if (! outbuf->output || inbuf->output)
  2027.     abort ();
  2028.  
  2029.     while (1)
  2030.     {
  2031.     struct buffer_data *data;
  2032.     int need;
  2033.     union
  2034.     {
  2035.         char intbuf[sizeof (int)];
  2036.         int i;
  2037.     } u;
  2038.     char *intp;
  2039.     int count;
  2040.     struct buffer_data *start;
  2041.     int startoff;
  2042.     struct buffer_data *stop;
  2043.     int stopwant;
  2044.  
  2045.     /* See if we have enough bytes to figure out the count.  */
  2046.     need = sizeof (int);
  2047.     intp = u.intbuf;
  2048.     for (data = inbuf->data; data != NULL; data = data->next)
  2049.     {
  2050.         if (data->size >= need)
  2051.         {
  2052.         memcpy (intp, data->bufp, need);
  2053.         break;
  2054.         }
  2055.         memcpy (intp, data->bufp, data->size);
  2056.         intp += data->size;
  2057.         need -= data->size;
  2058.     }
  2059.     if (data == NULL)
  2060.     {
  2061.         /* We don't have enough bytes to form an integer.  */
  2062.         return need;
  2063.     }
  2064.  
  2065.     count = u.i;
  2066.     start = data;
  2067.     startoff = need;
  2068.  
  2069.     /*
  2070.      * We have an integer in COUNT.  We have gotten all the data
  2071.      * from INBUF in all buffers before START, and we have gotten
  2072.      * STARTOFF bytes from START.  See if we have enough bytes
  2073.      * remaining in INBUF.
  2074.      */
  2075.     need = count - (start->size - startoff);
  2076.     if (need <= 0)
  2077.     {
  2078.         stop = start;
  2079.         stopwant = count;
  2080.     }
  2081.     else
  2082.     {
  2083.         for (data = start->next; data != NULL; data = data->next)
  2084.         {
  2085.         if (need <= data->size)
  2086.             break;
  2087.         need -= data->size;
  2088.         }
  2089.         if (data == NULL)
  2090.         {
  2091.         /* We don't have enough bytes.  */
  2092.         return need;
  2093.         }
  2094.         stop = data;
  2095.         stopwant = need;
  2096.     }
  2097.  
  2098.     /*
  2099.      * We have enough bytes.  Free any buffers in INBUF before
  2100.      * START, and remove STARTOFF bytes from START, so that we can
  2101.      * forget about STARTOFF.
  2102.      */
  2103.     start->bufp += startoff;
  2104.     start->size -= startoff;
  2105.  
  2106.     if (start->size == 0)
  2107.         start = start->next;
  2108.  
  2109.     if (stop->size == stopwant)
  2110.     {
  2111.         stop = stop->next;
  2112.         stopwant = 0;
  2113.     }
  2114.  
  2115.     while (inbuf->data != start)
  2116.     {
  2117.         data = inbuf->data;
  2118.         inbuf->data = data->next;
  2119.         data->next = free_buffer_data;
  2120.         free_buffer_data = data;
  2121.     }
  2122.  
  2123.     /*
  2124.      * We want to copy over the bytes from START through STOP.  We
  2125.      * only want STOPWANT bytes from STOP.
  2126.      */
  2127.  
  2128.     if (start != stop)
  2129.     {
  2130.         /* Attach the buffers from START through STOP to OUTBUF.  */
  2131.         for (data = start; data->next != stop; data = data->next)
  2132.         ;
  2133.         inbuf->data = stop;
  2134.         data->next = NULL;
  2135.         buf_append_data (outbuf, start, data);
  2136.     }
  2137.  
  2138.     if (stopwant > 0)
  2139.     {
  2140.         buf_output (outbuf, stop->bufp, stopwant);
  2141.         stop->bufp += stopwant;
  2142.         stop->size -= stopwant;
  2143.     }
  2144.     }
  2145.  
  2146.     /*NOTREACHED*/
  2147. }
  2148.  
  2149. /* While processing requests, this buffer accumulates data to be sent to
  2150.    the client, and then once we are in do_cvs_command, we use it
  2151.    for all the data to be sent.  */
  2152. static struct buffer buf_to_net;
  2153.  
  2154. static void serve_questionable PROTO((char *));
  2155.  
  2156. static void
  2157. serve_questionable (arg)
  2158.     char *arg;
  2159. {
  2160.     static int initted;
  2161.  
  2162.     if (!initted)
  2163.     {
  2164.     /* Pick up ignores from CVSROOTADM_IGNORE, $HOME/.cvsignore on server,
  2165.        and CVSIGNORE on server.  */
  2166.     ign_setup ();
  2167.     initted = 1;
  2168.     }
  2169.  
  2170.     if (dir_name == NULL)
  2171.     {
  2172.     buf_output0 (&buf_to_net, "E Protocol error: 'Directory' missing");
  2173.     return;
  2174.     }
  2175.  
  2176.     if (!ign_name (arg))
  2177.     {
  2178.     char *update_dir;
  2179.  
  2180.     buf_output (&buf_to_net, "M ? ", 4);
  2181.     update_dir = dir_name + strlen (server_temp_dir) + 1;
  2182.     if (!(update_dir[0] == '.' && update_dir[1] == '\0'))
  2183.     {
  2184.         buf_output0 (&buf_to_net, update_dir);
  2185.         buf_output (&buf_to_net, "/", 1);
  2186.     }
  2187.     buf_output0 (&buf_to_net, arg);
  2188.     buf_output (&buf_to_net, "\n", 1);
  2189.     }
  2190. }
  2191.  
  2192. static void serve_case PROTO ((char *));
  2193.  
  2194. static void
  2195. serve_case (arg)
  2196.     char *arg;
  2197. {
  2198.     ign_case = 1;
  2199. }
  2200.  
  2201. static struct buffer protocol;
  2202.  
  2203. /* This is the output which we are saving up to send to the server, in the
  2204.    child process.  We will push it through, via the `protocol' buffer, when
  2205.    we have a complete line.  */
  2206. static struct buffer saved_output;
  2207. /* Likewise, but stuff which will go to stderr.  */
  2208. static struct buffer saved_outerr;
  2209.  
  2210. static void
  2211. protocol_memory_error (buf)
  2212.     struct buffer *buf;
  2213. {
  2214.     error (1, ENOMEM, "Virtual memory exhausted");
  2215. }
  2216.  
  2217. /*
  2218.  * Process IDs of the subprocess, or negative if that subprocess
  2219.  * does not exist.
  2220.  */
  2221. static pid_t command_pid;
  2222.  
  2223. static void
  2224. outbuf_memory_error (buf)
  2225.     struct buffer *buf;
  2226. {
  2227.     static const char msg[] = "E Fatal server error\n\
  2228. error ENOMEM Virtual memory exhausted.\n";
  2229.     if (command_pid > 0)
  2230.     kill (command_pid, SIGTERM);
  2231.  
  2232.     /*
  2233.      * We have arranged things so that printing this now either will
  2234.      * be legal, or the "E fatal error" line will get glommed onto the
  2235.      * end of an existing "E" or "M" response.
  2236.      */
  2237.  
  2238.     /* If this gives an error, not much we could do.  syslog() it?  */
  2239.     write (STDOUT_FILENO, msg, sizeof (msg) - 1);
  2240.     server_cleanup (0);
  2241.     exit (EXIT_FAILURE);
  2242. }
  2243.  
  2244. static void
  2245. input_memory_error (buf)
  2246.      struct buffer *buf;
  2247. {
  2248.     outbuf_memory_error (buf);
  2249. }
  2250.  
  2251. /* Execute COMMAND in a subprocess with the approriate funky things done.  */
  2252.  
  2253. static struct fd_set_wrapper { fd_set fds; } command_fds_to_drain;
  2254. static int max_command_fd;
  2255.  
  2256. #ifdef SERVER_FLOWCONTROL
  2257. static int flowcontrol_pipe[2];
  2258. #endif /* SERVER_FLOWCONTROL */
  2259.  
  2260. static void
  2261. do_cvs_command (command)
  2262.     int (*command) PROTO((int argc, char **argv));
  2263. {
  2264.     /*
  2265.      * The following file descriptors are set to -1 if that file is not
  2266.      * currently open.
  2267.      */
  2268.  
  2269.     /* Data on these pipes is a series of '\n'-terminated lines.  */
  2270.     int stdout_pipe[2];
  2271.     int stderr_pipe[2];
  2272.  
  2273.     /*
  2274.      * Data on this pipe is a series of counted (see buf_send_counted)
  2275.      * packets.  Each packet must be processed atomically (i.e. not
  2276.      * interleaved with data from stdout_pipe or stderr_pipe).
  2277.      */
  2278.     int protocol_pipe[2];
  2279.     
  2280.     int dev_null_fd = -1;
  2281.  
  2282.     int errs;
  2283.  
  2284.     command_pid = -1;
  2285.     stdout_pipe[0] = -1;
  2286.     stdout_pipe[1] = -1;
  2287.     stderr_pipe[0] = -1;
  2288.     stderr_pipe[1] = -1;
  2289.     protocol_pipe[0] = -1;
  2290.     protocol_pipe[1] = -1;
  2291.  
  2292.     server_write_entries ();
  2293.  
  2294.     if (print_pending_error ())
  2295.     goto free_args_and_return;
  2296.  
  2297.     (void) server_notify ();
  2298.  
  2299.     /*
  2300.      * We use a child process which actually does the operation.  This
  2301.      * is so we can intercept its standard output.  Even if all of CVS
  2302.      * were written to go to some special routine instead of writing
  2303.      * to stdout or stderr, we would still need to do the same thing
  2304.      * for the RCS commands.
  2305.      */
  2306.  
  2307.     if (pipe (stdout_pipe) < 0)
  2308.     {
  2309.     print_error (errno);
  2310.     goto error_exit;
  2311.     }
  2312.     if (pipe (stderr_pipe) < 0)
  2313.     {
  2314.     print_error (errno);
  2315.     goto error_exit;
  2316.     }
  2317.     if (pipe (protocol_pipe) < 0)
  2318.     {
  2319.     print_error (errno);
  2320.     goto error_exit;
  2321.     }
  2322. #ifdef SERVER_FLOWCONTROL
  2323.     if (pipe (flowcontrol_pipe) < 0)
  2324.     {
  2325.     print_error (errno);
  2326.     goto error_exit;
  2327.     }
  2328.     set_nonblock_fd (flowcontrol_pipe[0]);
  2329.     set_nonblock_fd (flowcontrol_pipe[1]);
  2330. #endif /* SERVER_FLOWCONTROL */
  2331.  
  2332.     dev_null_fd = open ("/dev/null", O_RDONLY);
  2333.     if (dev_null_fd < 0)
  2334.     {
  2335.     print_error (errno);
  2336.     goto error_exit;
  2337.     }
  2338.  
  2339.     /* Don't use vfork; we're not going to exec().  */
  2340.     command_pid = fork ();
  2341.     if (command_pid < 0)
  2342.     {
  2343.     print_error (errno);
  2344.     goto error_exit;
  2345.     }
  2346.     if (command_pid == 0)
  2347.     {
  2348.     int exitstatus;
  2349.  
  2350.     /* Since we're in the child, and the parent is going to take
  2351.        care of packaging up our error messages, we can clear this
  2352.        flag.  */
  2353.     error_use_protocol = 0;
  2354.  
  2355.     protocol.data = protocol.last = NULL;
  2356.     protocol.fd = protocol_pipe[1];
  2357.     protocol.output = 1;
  2358.     protocol.nonblocking = 0;
  2359.     protocol.memory_error = protocol_memory_error;
  2360.  
  2361.     saved_output.data = saved_output.last = NULL;
  2362.     saved_output.fd = -1;
  2363.     saved_output.output = 0;
  2364.     saved_output.nonblocking = 0;
  2365.     saved_output.memory_error = protocol_memory_error;
  2366.     saved_outerr = saved_output;
  2367.  
  2368.     if (dup2 (dev_null_fd, STDIN_FILENO) < 0)
  2369.         error (1, errno, "can't set up pipes");
  2370.     if (dup2 (stdout_pipe[1], STDOUT_FILENO) < 0)
  2371.         error (1, errno, "can't set up pipes");
  2372.     if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0)
  2373.         error (1, errno, "can't set up pipes");
  2374.     close (stdout_pipe[0]);
  2375.     close (stderr_pipe[0]);
  2376.     close (protocol_pipe[0]);
  2377. #ifdef SERVER_FLOWCONTROL
  2378.     close (flowcontrol_pipe[1]);
  2379. #endif /* SERVER_FLOWCONTROL */
  2380.  
  2381.     /*
  2382.      * Set this in .bashrc if you want to give yourself time to attach
  2383.      * to the subprocess with a debugger.
  2384.      */
  2385.     if (getenv ("CVS_SERVER_SLEEP"))
  2386.     {
  2387.         int secs = atoi (getenv ("CVS_SERVER_SLEEP"));
  2388.         sleep (secs);
  2389.     }
  2390.  
  2391.     exitstatus = (*command) (argument_count, argument_vector);
  2392.  
  2393.     /*
  2394.      * When we exit, that will close the pipes, giving an EOF to
  2395.      * the parent.
  2396.      */
  2397.     exit (exitstatus);
  2398.     }
  2399.  
  2400.     /* OK, sit around getting all the input from the child.  */
  2401.     {
  2402.     struct buffer stdoutbuf;
  2403.     struct buffer stderrbuf;
  2404.     struct buffer protocol_inbuf;
  2405.     /* Number of file descriptors to check in select ().  */
  2406.     int num_to_check;
  2407.     int count_needed = 0;
  2408. #ifdef SERVER_FLOWCONTROL
  2409.     int have_flowcontrolled = 0;
  2410. #endif /* SERVER_FLOWCONTROL */
  2411.  
  2412.     FD_ZERO (&command_fds_to_drain.fds);
  2413.     num_to_check = stdout_pipe[0];
  2414.     FD_SET (stdout_pipe[0], &command_fds_to_drain.fds);
  2415.     if (stderr_pipe[0] > num_to_check)
  2416.       num_to_check = stderr_pipe[0];
  2417.     FD_SET (stderr_pipe[0], &command_fds_to_drain.fds);
  2418.     if (protocol_pipe[0] > num_to_check)
  2419.       num_to_check = protocol_pipe[0];
  2420.     FD_SET (protocol_pipe[0], &command_fds_to_drain.fds);
  2421.     if (STDOUT_FILENO > num_to_check)
  2422.       num_to_check = STDOUT_FILENO;
  2423.     max_command_fd = num_to_check;
  2424.     /*
  2425.      * File descriptors are numbered from 0, so num_to_check needs to
  2426.      * be one larger than the largest descriptor.
  2427.      */
  2428.     ++num_to_check;
  2429.     if (num_to_check > FD_SETSIZE)
  2430.     {
  2431.         printf ("E internal error: FD_SETSIZE not big enough.\nerror  \n");
  2432.         goto error_exit;
  2433.     }
  2434.  
  2435.     stdoutbuf.data = stdoutbuf.last = NULL;
  2436.     stdoutbuf.fd = stdout_pipe[0];
  2437.     stdoutbuf.output = 0;
  2438.     stdoutbuf.nonblocking = 0;
  2439.     stdoutbuf.memory_error = input_memory_error;
  2440.  
  2441.     stderrbuf.data = stderrbuf.last = NULL;
  2442.     stderrbuf.fd = stderr_pipe[0];
  2443.     stderrbuf.output = 0;
  2444.     stderrbuf.nonblocking = 0;
  2445.     stderrbuf.memory_error = input_memory_error;
  2446.  
  2447.     protocol_inbuf.data = protocol_inbuf.last = NULL;
  2448.     protocol_inbuf.fd = protocol_pipe[0];
  2449.     protocol_inbuf.output = 0;
  2450.     protocol_inbuf.nonblocking = 0;
  2451.     protocol_inbuf.memory_error = input_memory_error;
  2452.  
  2453.     set_nonblock (&buf_to_net);
  2454.     set_nonblock (&stdoutbuf);
  2455.     set_nonblock (&stderrbuf);
  2456.     set_nonblock (&protocol_inbuf);
  2457.  
  2458.     if (close (stdout_pipe[1]) < 0)
  2459.     {
  2460.         print_error (errno);
  2461.         goto error_exit;
  2462.     }
  2463.     stdout_pipe[1] = -1;
  2464.  
  2465.     if (close (stderr_pipe[1]) < 0)
  2466.     {
  2467.         print_error (errno);
  2468.         goto error_exit;
  2469.     }
  2470.     stderr_pipe[1] = -1;
  2471.  
  2472.     if (close (protocol_pipe[1]) < 0)
  2473.     {
  2474.         print_error (errno);
  2475.         goto error_exit;
  2476.     }
  2477.     protocol_pipe[1] = -1;
  2478.  
  2479. #ifdef SERVER_FLOWCONTROL
  2480.     if (close (flowcontrol_pipe[0]) < 0)
  2481.     {
  2482.         print_error (errno);
  2483.         goto error_exit;
  2484.     }
  2485.     flowcontrol_pipe[0] = -1;
  2486. #endif /* SERVER_FLOWCONTROL */
  2487.  
  2488.     if (close (dev_null_fd) < 0)
  2489.     {
  2490.         print_error (errno);
  2491.         goto error_exit;
  2492.     }
  2493.     dev_null_fd = -1;
  2494.  
  2495.     while (stdout_pipe[0] >= 0
  2496.            || stderr_pipe[0] >= 0
  2497.            || protocol_pipe[0] >= 0)
  2498.     {
  2499.         fd_set readfds;
  2500.         fd_set writefds;
  2501.         int numfds;
  2502. #ifdef SERVER_FLOWCONTROL
  2503.         int bufmemsize;
  2504.  
  2505.         /*
  2506.          * See if we are swamping the remote client and filling our VM.
  2507.          * Tell child to hold off if we do.
  2508.          */
  2509.         bufmemsize = buf_count_mem (&buf_to_net);
  2510.         if (!have_flowcontrolled && (bufmemsize > SERVER_HI_WATER))
  2511.         {
  2512.         if (write(flowcontrol_pipe[1], "S", 1) == 1)
  2513.             have_flowcontrolled = 1;
  2514.         }
  2515.         else if (have_flowcontrolled && (bufmemsize < SERVER_LO_WATER))
  2516.         {
  2517.         if (write(flowcontrol_pipe[1], "G", 1) == 1)
  2518.             have_flowcontrolled = 0;
  2519.         }
  2520. #endif /* SERVER_FLOWCONTROL */
  2521.  
  2522.         FD_ZERO (&readfds);
  2523.         FD_ZERO (&writefds);
  2524.         if (! buf_empty_p (&buf_to_net))
  2525.             FD_SET (STDOUT_FILENO, &writefds);
  2526.  
  2527.         if (stdout_pipe[0] >= 0)
  2528.         {
  2529.         FD_SET (stdout_pipe[0], &readfds);
  2530.         }
  2531.         if (stderr_pipe[0] >= 0)
  2532.         {
  2533.         FD_SET (stderr_pipe[0], &readfds);
  2534.         }
  2535.         if (protocol_pipe[0] >= 0)
  2536.         {
  2537.         FD_SET (protocol_pipe[0], &readfds);
  2538.         }
  2539.  
  2540.         do {
  2541.         /* This used to select on exceptions too, but as far
  2542.                    as I know there was never any reason to do that and
  2543.                    SCO doesn't let you select on exceptions on pipes.  */
  2544.         numfds = select (num_to_check, &readfds, &writefds,
  2545.                  (fd_set *)0, (struct timeval *)NULL);
  2546.         if (numfds < 0
  2547.             && errno != EINTR)
  2548.         {
  2549.             print_error (errno);
  2550.             goto error_exit;
  2551.         }
  2552.         } while (numfds < 0);
  2553.         
  2554.         if (FD_ISSET (STDOUT_FILENO, &writefds))
  2555.         {
  2556.         /* What should we do with errors?  syslog() them?  */
  2557.         buf_send_output (&buf_to_net);
  2558.         }
  2559.  
  2560.         if (stdout_pipe[0] >= 0
  2561.         && (FD_ISSET (stdout_pipe[0], &readfds)))
  2562.         {
  2563.             int status;
  2564.  
  2565.             status = buf_input_data (&stdoutbuf, (int *) NULL);
  2566.  
  2567.         buf_copy_lines (&buf_to_net, &stdoutbuf, 'M');
  2568.  
  2569.         if (status == -1)
  2570.             stdout_pipe[0] = -1;
  2571.         else if (status > 0)
  2572.         {
  2573.             print_error (status);
  2574.             goto error_exit;
  2575.         }
  2576.  
  2577.         /* What should we do with errors?  syslog() them?  */
  2578.         buf_send_output (&buf_to_net);
  2579.         }
  2580.  
  2581.         if (stderr_pipe[0] >= 0
  2582.         && (FD_ISSET (stderr_pipe[0], &readfds)))
  2583.         {
  2584.             int status;
  2585.  
  2586.             status = buf_input_data (&stderrbuf, (int *) NULL);
  2587.  
  2588.         buf_copy_lines (&buf_to_net, &stderrbuf, 'E');
  2589.  
  2590.         if (status == -1)
  2591.             stderr_pipe[0] = -1;
  2592.         else if (status > 0)
  2593.         {
  2594.             print_error (status);
  2595.             goto error_exit;
  2596.         }
  2597.  
  2598.         /* What should we do with errors?  syslog() them?  */
  2599.         buf_send_output (&buf_to_net);
  2600.         }
  2601.  
  2602.         if (protocol_pipe[0] >= 0
  2603.         && (FD_ISSET (protocol_pipe[0], &readfds)))
  2604.         {
  2605.         int status;
  2606.         int count_read;
  2607.         
  2608.         status = buf_input_data (&protocol_inbuf, &count_read);
  2609.  
  2610.         /*
  2611.          * We only call buf_copy_counted if we have read
  2612.          * enough bytes to make it worthwhile.  This saves us
  2613.          * from continually recounting the amount of data we
  2614.          * have.
  2615.          */
  2616.         count_needed -= count_read;
  2617.         if (count_needed <= 0)
  2618.             count_needed = buf_copy_counted (&buf_to_net,
  2619.                              &protocol_inbuf);
  2620.  
  2621.         if (status == -1)
  2622.             protocol_pipe[0] = -1;
  2623.         else if (status > 0)
  2624.         {
  2625.             print_error (status);
  2626.             goto error_exit;
  2627.         }
  2628.  
  2629.         /* What should we do with errors?  syslog() them?  */
  2630.         buf_send_output (&buf_to_net);
  2631.         }
  2632.     }
  2633.  
  2634.     /*
  2635.      * OK, we've gotten EOF on all the pipes.  If there is
  2636.      * anything left on stdoutbuf or stderrbuf (this could only
  2637.      * happen if there was no trailing newline), send it over.
  2638.      */
  2639.     if (! buf_empty_p (&stdoutbuf))
  2640.     {
  2641.         buf_append_char (&stdoutbuf, '\n');
  2642.         buf_copy_lines (&buf_to_net, &stdoutbuf, 'M');
  2643.     }
  2644.     if (! buf_empty_p (&stderrbuf))
  2645.     {
  2646.         buf_append_char (&stderrbuf, '\n');
  2647.         buf_copy_lines (&buf_to_net, &stderrbuf, 'E');
  2648.     }
  2649.     if (! buf_empty_p (&protocol_inbuf))
  2650.         buf_output0 (&buf_to_net,
  2651.              "E Protocol error: uncounted data discarded\n");
  2652.  
  2653.     errs = 0;
  2654.  
  2655.     while (command_pid > 0)
  2656.     {
  2657.         int status;
  2658.         pid_t waited_pid;
  2659.         waited_pid = waitpid (command_pid, &status, 0);
  2660.         if (waited_pid < 0)
  2661.         {
  2662.         /*
  2663.          * Intentionally ignoring EINTR.  Other errors
  2664.          * "can't happen".
  2665.          */
  2666.         continue;
  2667.         }
  2668.         
  2669.         if (WIFEXITED (status))
  2670.         errs += WEXITSTATUS (status);
  2671.         else
  2672.         {
  2673.             int sig = WTERMSIG (status);
  2674.         /*
  2675.          * This is really evil, because signals might be numbered
  2676.          * differently on the two systems.  We should be using
  2677.          * signal names (either of the "Terminated" or the "SIGTERM"
  2678.          * variety).  But cvs doesn't currently use libiberty...we
  2679.          * could roll our own....  FIXME.
  2680.          */
  2681.         printf ("E Terminated with fatal signal %d\n", sig);
  2682.  
  2683.         /* Test for a core dump.  Is this portable?  */
  2684.         if (status & 0x80)
  2685.         {
  2686.             printf ("E Core dumped; preserving %s on server.\n\
  2687. E CVS locks may need cleaning up.\n",
  2688.                 server_temp_dir);
  2689.             dont_delete_temp = 1;
  2690.         }
  2691.         ++errs;
  2692.         }
  2693.         if (waited_pid == command_pid)
  2694.         command_pid = -1;
  2695.     }
  2696.  
  2697.     /*
  2698.      * OK, we've waited for the child.  By now all CVS locks are free
  2699.      * and it's OK to block on the network.
  2700.      */
  2701.     set_block (&buf_to_net);
  2702.     buf_send_output (&buf_to_net);
  2703.     }
  2704.  
  2705.     if (errs)
  2706.     /* We will have printed an error message already.  */
  2707.     printf ("error  \n");
  2708.     else
  2709.     printf ("ok\n");
  2710.     goto free_args_and_return;
  2711.  
  2712.  error_exit:
  2713.     if (command_pid > 0)
  2714.     kill (command_pid, SIGTERM);
  2715.  
  2716.     while (command_pid > 0)
  2717.     {
  2718.     pid_t waited_pid;
  2719.     waited_pid = waitpid (command_pid, (int *) 0, 0);
  2720.     if (waited_pid < 0 && errno == EINTR)
  2721.         continue;
  2722.     if (waited_pid == command_pid)
  2723.         command_pid = -1;
  2724.     }
  2725.  
  2726.     close (dev_null_fd);
  2727.     close (protocol_pipe[0]);
  2728.     close (protocol_pipe[1]);
  2729.     close (stderr_pipe[0]);
  2730.     close (stderr_pipe[1]);
  2731.     close (stdout_pipe[0]);
  2732.     close (stdout_pipe[1]);
  2733.  
  2734.  free_args_and_return:
  2735.     /* Now free the arguments.  */
  2736.     {
  2737.     /* argument_vector[0] is a dummy argument, we don't mess with it.  */
  2738.     char **cp;
  2739.     for (cp = argument_vector + 1;
  2740.          cp < argument_vector + argument_count;
  2741.          ++cp)
  2742.         free (*cp);
  2743.  
  2744.     argument_count = 1;
  2745.     }
  2746.     return;
  2747. }
  2748.  
  2749. #ifdef SERVER_FLOWCONTROL
  2750. /*
  2751.  * Called by the child at convenient points in the server's execution for
  2752.  * the server child to block.. ie: when it has no locks active.
  2753.  */
  2754. void
  2755. server_pause_check()
  2756. {
  2757.     int paused = 0;
  2758.     char buf[1];
  2759.  
  2760.     while (read (flowcontrol_pipe[0], buf, 1) == 1)
  2761.     {
  2762.     if (*buf == 'S')    /* Stop */
  2763.         paused = 1;
  2764.     else if (*buf == 'G')    /* Go */
  2765.         paused = 0;
  2766.     else
  2767.         return;        /* ??? */
  2768.     }
  2769.     while (paused) {
  2770.     int numfds, numtocheck;
  2771.     fd_set fds;
  2772.  
  2773.     FD_ZERO (&fds);
  2774.     FD_SET (flowcontrol_pipe[0], &fds);
  2775.     numtocheck = flowcontrol_pipe[0] + 1;
  2776.     
  2777.     do {
  2778.         numfds = select (numtocheck, &fds, (fd_set *)0,
  2779.                  (fd_set *)0, (struct timeval *)NULL);
  2780.         if (numfds < 0
  2781.         && errno != EINTR)
  2782.         {
  2783.         print_error (errno);
  2784.         return;
  2785.         }
  2786.     } while (numfds < 0);
  2787.         
  2788.     if (FD_ISSET (flowcontrol_pipe[0], &fds))
  2789.     {
  2790.         while (read (flowcontrol_pipe[0], buf, 1) == 1)
  2791.         {
  2792.         if (*buf == 'S')    /* Stop */
  2793.             paused = 1;
  2794.         else if (*buf == 'G')    /* Go */
  2795.             paused = 0;
  2796.         else
  2797.             return;        /* ??? */
  2798.         }
  2799.     }
  2800.     }
  2801. }
  2802. #endif /* SERVER_FLOWCONTROL */
  2803.  
  2804. static void output_dir PROTO((char *, char *));
  2805.  
  2806. static void
  2807. output_dir (update_dir, repository)
  2808.     char *update_dir;
  2809.     char *repository;
  2810. {
  2811.     if (use_dir_and_repos)
  2812.     {
  2813.     if (update_dir[0] == '\0')
  2814.         buf_output0 (&protocol, ".");
  2815.     else
  2816.         buf_output0 (&protocol, update_dir);
  2817.     buf_output0 (&protocol, "/\n");
  2818.     }
  2819.     buf_output0 (&protocol, repository);
  2820.     buf_output0 (&protocol, "/");
  2821. }
  2822.  
  2823. /*
  2824.  * Entries line that we are squirreling away to send to the client when
  2825.  * we are ready.
  2826.  */
  2827. static char *entries_line;
  2828.  
  2829. /*
  2830.  * File which has been Scratch_File'd, we are squirreling away that fact
  2831.  * to inform the client when we are ready.
  2832.  */
  2833. static char *scratched_file;
  2834.  
  2835. /*
  2836.  * The scratched_file will need to be removed as well as having its entry
  2837.  * removed.
  2838.  */
  2839. static int kill_scratched_file;
  2840.  
  2841. void
  2842. server_register (name, version, timestamp, options, tag, date, conflict)
  2843.     char *name;
  2844.     char *version;
  2845.     char *timestamp;
  2846.     char *options;
  2847.     char *tag;
  2848.     char *date;
  2849.     char *conflict;
  2850. {
  2851.     int len;
  2852.  
  2853.     if (options == NULL)
  2854.     options = "";
  2855.  
  2856.     if (trace)
  2857.     {
  2858.     (void) fprintf (stderr,
  2859.             "%c-> server_register(%s, %s, %s, %s, %s, %s, %s)\n",
  2860.             (server_active) ? 'S' : ' ', /* silly */
  2861.             name, version, timestamp, options, tag ? tag : "",
  2862.             date ? date : "", conflict ? conflict : "");
  2863.     }
  2864.  
  2865.     if (entries_line != NULL)
  2866.     {
  2867.     /*
  2868.      * If CVS decides to Register it more than once (which happens
  2869.      * on "cvs update foo/foo.c" where foo and foo.c are already
  2870.      * checked out), use the last of the entries lines Register'd.
  2871.      */
  2872.     free (entries_line);
  2873.     }
  2874.  
  2875.     /*
  2876.      * I have reports of Scratch_Entry and Register both happening, in
  2877.      * two different cases.  Using the last one which happens is almost
  2878.      * surely correct; I haven't tracked down why they both happen (or
  2879.      * even verified that they are for the same file).
  2880.      */
  2881.     if (scratched_file != NULL)
  2882.     {
  2883.     free (scratched_file);
  2884.     scratched_file = NULL;
  2885.     }
  2886.  
  2887.     len = (strlen (name) + strlen (version) + strlen (options) + 80);
  2888.     if (tag)
  2889.     len += strlen (tag);
  2890.     if (date)
  2891.     len += strlen (date);
  2892.     
  2893.     entries_line = xmalloc (len);
  2894.     sprintf (entries_line, "/%s/%s/", name, version);
  2895.     if (conflict != NULL)
  2896.     {
  2897.     strcat (entries_line, "+=");
  2898.     }
  2899.     strcat (entries_line, "/");
  2900.     strcat (entries_line, options);
  2901.     strcat (entries_line, "/");
  2902.     if (tag != NULL)
  2903.     {
  2904.     strcat (entries_line, "T");
  2905.     strcat (entries_line, tag);
  2906.     }
  2907.     else if (date != NULL)
  2908.     {
  2909.     strcat (entries_line, "D");
  2910.     strcat (entries_line, date);
  2911.     }
  2912. }
  2913.  
  2914. void
  2915. server_scratch (fname)
  2916.     char *fname;
  2917. {
  2918.     /*
  2919.      * I have reports of Scratch_Entry and Register both happening, in
  2920.      * two different cases.  Using the last one which happens is almost
  2921.      * surely correct; I haven't tracked down why they both happen (or
  2922.      * even verified that they are for the same file).
  2923.      */
  2924.     if (entries_line != NULL)
  2925.     {
  2926.     free (entries_line);
  2927.     entries_line = NULL;
  2928.     }
  2929.  
  2930.     if (scratched_file != NULL)
  2931.     {
  2932.     buf_output0 (&protocol,
  2933.              "E CVS server internal error: duplicate Scratch_Entry\n");
  2934.     buf_send_counted (&protocol);
  2935.     return;
  2936.     }
  2937.     scratched_file = xstrdup (fname);
  2938.     kill_scratched_file = 1;
  2939. }
  2940.  
  2941. void
  2942. server_scratch_entry_only ()
  2943. {
  2944.     kill_scratched_file = 0;
  2945. }
  2946.  
  2947. /* Print a new entries line, from a previous server_register.  */
  2948. static void
  2949. new_entries_line ()
  2950. {
  2951.     if (entries_line)
  2952.     {
  2953.     buf_output0 (&protocol, entries_line);
  2954.     buf_output (&protocol, "\n", 1);
  2955.     }
  2956.     else
  2957.     /* Return the error message as the Entries line.  */
  2958.     buf_output0 (&protocol,
  2959.              "CVS server internal error: Register missing\n");
  2960.     free (entries_line);
  2961.     entries_line = NULL;
  2962. }
  2963.  
  2964. static void
  2965. serve_ci (arg)
  2966.     char *arg;
  2967. {
  2968.     do_cvs_command (commit);
  2969. }
  2970.  
  2971. static void
  2972. checked_in_response (file, update_dir, repository)
  2973.     char *file;
  2974.     char *update_dir;
  2975.     char *repository;
  2976. {
  2977.     if (supported_response ("Mode"))
  2978.     {
  2979.     struct stat sb;
  2980.     char *mode_string;
  2981.  
  2982.     if (stat (file, &sb) < 0)
  2983.     {
  2984.         /* Not clear to me why the file would fail to exist, but it
  2985.            was happening somewhere in the testsuite.  */
  2986.         if (!existence_error (errno))
  2987.         error (0, errno, "cannot stat %s", file);
  2988.     }
  2989.     else
  2990.     {
  2991.         buf_output0 (&protocol, "Mode ");
  2992.         mode_string = mode_to_string (sb.st_mode);
  2993.         buf_output0 (&protocol, mode_string);
  2994.         buf_output0 (&protocol, "\n");
  2995.         free (mode_string);
  2996.     }
  2997.     }
  2998.  
  2999.     buf_output0 (&protocol, "Checked-in ");
  3000.     output_dir (update_dir, repository);
  3001.     buf_output0 (&protocol, file);
  3002.     buf_output (&protocol, "\n", 1);
  3003.     new_entries_line ();
  3004. }
  3005.  
  3006. void
  3007. server_checked_in (file, update_dir, repository)
  3008.     char *file;
  3009.     char *update_dir;
  3010.     char *repository;
  3011. {
  3012.     if (noexec)
  3013.     return;
  3014.     if (scratched_file != NULL && entries_line == NULL)
  3015.     {
  3016.     /*
  3017.      * This happens if we are now doing a "cvs remove" after a previous
  3018.      * "cvs add" (without a "cvs ci" in between).
  3019.      */
  3020.     buf_output0 (&protocol, "Remove-entry ");
  3021.     output_dir (update_dir, repository);
  3022.     buf_output0 (&protocol, file);
  3023.     buf_output (&protocol, "\n", 1);
  3024.     free (scratched_file);
  3025.     scratched_file = NULL;
  3026.     }
  3027.     else
  3028.     {
  3029.     checked_in_response (file, update_dir, repository);
  3030.     }
  3031.     buf_send_counted (&protocol);
  3032. }
  3033.  
  3034. void
  3035. server_update_entries (file, update_dir, repository, updated)
  3036.     char *file;
  3037.     char *update_dir;
  3038.     char *repository;
  3039.     enum server_updated_arg4 updated;
  3040. {
  3041.     if (noexec)
  3042.     return;
  3043.     if (updated == SERVER_UPDATED)
  3044.     checked_in_response (file, update_dir, repository);
  3045.     else
  3046.     {
  3047.     if (!supported_response ("New-entry"))
  3048.         return;
  3049.     buf_output0 (&protocol, "New-entry ");
  3050.     output_dir (update_dir, repository);
  3051.     buf_output0 (&protocol, file);
  3052.     buf_output (&protocol, "\n", 1);
  3053.     new_entries_line ();
  3054.     }
  3055.  
  3056.     buf_send_counted (&protocol);
  3057. }
  3058.  
  3059. static void
  3060. serve_update (arg)
  3061.     char *arg;
  3062. {
  3063.     do_cvs_command (update);
  3064. }
  3065.  
  3066. static void
  3067. serve_diff (arg)
  3068.     char *arg;
  3069. {
  3070.     do_cvs_command (diff);
  3071. }
  3072.  
  3073. static void
  3074. serve_log (arg)
  3075.     char *arg;
  3076. {
  3077.     do_cvs_command (cvslog);
  3078. }
  3079.  
  3080. static void
  3081. serve_add (arg)
  3082.     char *arg;
  3083. {
  3084.     do_cvs_command (add);
  3085. }
  3086.  
  3087. static void
  3088. serve_remove (arg)
  3089.     char *arg;
  3090. {
  3091.     do_cvs_command (cvsremove);
  3092. }
  3093.  
  3094. static void
  3095. serve_status (arg)
  3096.     char *arg;
  3097. {
  3098.     do_cvs_command (status);
  3099. }
  3100.  
  3101. static void
  3102. serve_rdiff (arg)
  3103.     char *arg;
  3104. {
  3105.     do_cvs_command (patch);
  3106. }
  3107.  
  3108. static void
  3109. serve_tag (arg)
  3110.     char *arg;
  3111. {
  3112.     do_cvs_command (tag);
  3113. }
  3114.  
  3115. static void
  3116. serve_rtag (arg)
  3117.     char *arg;
  3118. {
  3119.     do_cvs_command (rtag);
  3120. }
  3121.  
  3122. static void
  3123. serve_import (arg)
  3124.     char *arg;
  3125. {
  3126.     do_cvs_command (import);
  3127. }
  3128.  
  3129. static void
  3130. serve_admin (arg)
  3131.     char *arg;
  3132. {
  3133.     do_cvs_command (admin);
  3134. }
  3135.  
  3136. static void
  3137. serve_history (arg)
  3138.     char *arg;
  3139. {
  3140.     do_cvs_command (history);
  3141. }
  3142.  
  3143. static void
  3144. serve_release (arg)
  3145.     char *arg;
  3146. {
  3147.     do_cvs_command (release);
  3148. }
  3149.  
  3150. static void serve_watch_on PROTO ((char *));
  3151.  
  3152. static void
  3153. serve_watch_on (arg)
  3154.     char *arg;
  3155. {
  3156.     do_cvs_command (watch_on);
  3157. }
  3158.  
  3159. static void serve_watch_off PROTO ((char *));
  3160.  
  3161. static void
  3162. serve_watch_off (arg)
  3163.     char *arg;
  3164. {
  3165.     do_cvs_command (watch_off);
  3166. }
  3167.  
  3168. static void serve_watch_add PROTO ((char *));
  3169.  
  3170. static void
  3171. serve_watch_add (arg)
  3172.     char *arg;
  3173. {
  3174.     do_cvs_command (watch_add);
  3175. }
  3176.  
  3177. static void serve_watch_remove PROTO ((char *));
  3178.  
  3179. static void
  3180. serve_watch_remove (arg)
  3181.     char *arg;
  3182. {
  3183.     do_cvs_command (watch_remove);
  3184. }
  3185.  
  3186. static void serve_watchers PROTO ((char *));
  3187.  
  3188. static void
  3189. serve_watchers (arg)
  3190.     char *arg;
  3191. {
  3192.     do_cvs_command (watchers);
  3193. }
  3194.  
  3195. static void serve_editors PROTO ((char *));
  3196.  
  3197. static void
  3198. serve_editors (arg)
  3199.     char *arg;
  3200. {
  3201.     do_cvs_command (editors);
  3202. }
  3203.  
  3204. static int noop PROTO ((int, char **));
  3205.  
  3206. static int
  3207. noop (argc, argv)
  3208.     int argc;
  3209.     char **argv;
  3210. {
  3211.     return 0;
  3212. }
  3213.  
  3214. static void serve_noop PROTO ((char *));
  3215.  
  3216. static void
  3217. serve_noop (arg)
  3218.     char *arg;
  3219. {
  3220.     do_cvs_command (noop);
  3221. }
  3222.  
  3223. static void serve_init PROTO ((char *));
  3224.  
  3225. static void
  3226. serve_init (arg)
  3227.     char *arg;
  3228. {
  3229.     CVSroot = malloc (strlen (arg) + 1);
  3230.     if (CVSroot == NULL)
  3231.     {
  3232.     pending_error = ENOMEM;
  3233.     return;
  3234.     }
  3235.     strcpy (CVSroot, arg);
  3236.  
  3237.     do_cvs_command (init);
  3238. }
  3239.  
  3240. static void serve_annotate PROTO ((char *));
  3241.  
  3242. static void
  3243. serve_annotate (arg)
  3244.     char *arg;
  3245. {
  3246.     do_cvs_command (annotate);
  3247. }
  3248.  
  3249. static void
  3250. serve_co (arg)
  3251.     char *arg;
  3252. {
  3253.     char *tempdir;
  3254.     int status;
  3255.  
  3256.     if (print_pending_error ())
  3257.     return;
  3258.  
  3259.     if (!isdir (CVSADM))
  3260.     {
  3261.     /*
  3262.      * The client has not sent a "Repository" line.  Check out
  3263.      * into a pristine directory.
  3264.      */
  3265.     tempdir = malloc (strlen (server_temp_dir) + 80);
  3266.     if (tempdir == NULL)
  3267.     {
  3268.         printf ("E Out of memory\n");
  3269.         return;
  3270.     }
  3271.     strcpy (tempdir, server_temp_dir);
  3272.     strcat (tempdir, "/checkout-dir");
  3273.     status = mkdir_p (tempdir);
  3274.     if (status != 0 && status != EEXIST)
  3275.     {
  3276.         printf ("E Cannot create %s\n", tempdir);
  3277.         print_error (errno);
  3278.         free (tempdir);
  3279.         return;
  3280.     }
  3281.  
  3282.     if (chdir (tempdir) < 0)
  3283.     {
  3284.         printf ("E Cannot change to directory %s\n", tempdir);
  3285.         print_error (errno);
  3286.         free (tempdir);
  3287.         return;
  3288.     }
  3289.     free (tempdir);
  3290.     }
  3291.     do_cvs_command (checkout);
  3292. }
  3293.  
  3294. static void
  3295. serve_export (arg)
  3296.     char *arg;
  3297. {
  3298.     /* Tell checkout() to behave like export not checkout.  */
  3299.     command_name = "export";
  3300.     serve_co (arg);
  3301. }
  3302.  
  3303. void
  3304. server_copy_file (file, update_dir, repository, newfile)
  3305.     char *file;
  3306.     char *update_dir;
  3307.     char *repository;
  3308.     char *newfile;
  3309. {
  3310.     if (!supported_response ("Copy-file"))
  3311.     return;
  3312.     buf_output0 (&protocol, "Copy-file ");
  3313.     output_dir (update_dir, repository);
  3314.     buf_output0 (&protocol, file);
  3315.     buf_output0 (&protocol, "\n");
  3316.     buf_output0 (&protocol, newfile);
  3317.     buf_output0 (&protocol, "\n");
  3318. }
  3319.  
  3320. void
  3321. server_updated (file, update_dir, repository, updated, file_info, checksum)
  3322.     char *file;
  3323.     char *update_dir;
  3324.     char *repository;
  3325.     enum server_updated_arg4 updated;
  3326.     struct stat *file_info;
  3327.     unsigned char *checksum;
  3328. {
  3329.     char *short_pathname;
  3330.  
  3331.     if (noexec)
  3332.     return;
  3333.  
  3334.     short_pathname = xmalloc (strlen (update_dir) + strlen (file) + 10);
  3335.     if (update_dir[0] == '\0')
  3336.     strcpy (short_pathname, file);
  3337.     else
  3338.     sprintf (short_pathname, "%s/%s", update_dir, file);
  3339.  
  3340.     if (entries_line != NULL && scratched_file == NULL)
  3341.     {
  3342.     FILE *f;
  3343.     struct stat sb;
  3344.     struct buffer_data *list, *last;
  3345.     unsigned long size;
  3346.     char size_text[80];
  3347.  
  3348.     if (stat (file, &sb) < 0)
  3349.     {
  3350.         if (existence_error (errno))
  3351.         {
  3352.         /*
  3353.          * If we have a sticky tag for a branch on which the
  3354.          * file is dead, and cvs update the directory, it gets
  3355.          * a T_CHECKOUT but no file.  So in this case just
  3356.          * forget the whole thing.
  3357.          */
  3358.         free (entries_line);
  3359.         entries_line = NULL;
  3360.         goto done;
  3361.         }
  3362.         error (1, errno, "reading %s", short_pathname);
  3363.     }
  3364.  
  3365.     if (checksum != NULL)
  3366.     {
  3367.         static int checksum_supported = -1;
  3368.  
  3369.         if (checksum_supported == -1)
  3370.         {
  3371.         checksum_supported = supported_response ("Checksum");
  3372.         }
  3373.  
  3374.         if (checksum_supported)
  3375.         {
  3376.             int i;
  3377.         char buf[3];
  3378.  
  3379.             buf_output0 (&protocol, "Checksum ");
  3380.         for (i = 0; i < 16; i++)
  3381.         {
  3382.             sprintf (buf, "%02x", (unsigned int) checksum[i]);
  3383.             buf_output0 (&protocol, buf);
  3384.         }
  3385.         buf_append_char (&protocol, '\n');
  3386.         }
  3387.     }
  3388.  
  3389.     if (updated == SERVER_UPDATED)
  3390.         buf_output0 (&protocol, "Updated ");
  3391.     else if (updated == SERVER_MERGED)
  3392.         buf_output0 (&protocol, "Merged ");
  3393.     else if (updated == SERVER_PATCHED)
  3394.         buf_output0 (&protocol, "Patched ");
  3395.     else
  3396.         abort ();
  3397.     output_dir (update_dir, repository);
  3398.     buf_output0 (&protocol, file);
  3399.     buf_output (&protocol, "\n", 1);
  3400.  
  3401.     new_entries_line ();
  3402.  
  3403.         {
  3404.         char *mode_string;
  3405.  
  3406.         /* FIXME: When we check out files the umask of the server
  3407.            (set in .bashrc if rsh is in use, or set in main.c in
  3408.            the kerberos case, I think) affects what mode we send,
  3409.            and it shouldn't.  */
  3410.         if (file_info != NULL)
  3411.             mode_string = mode_to_string (file_info->st_mode);
  3412.         else
  3413.             mode_string = mode_to_string (sb.st_mode);
  3414.         buf_output0 (&protocol, mode_string);
  3415.         buf_output0 (&protocol, "\n");
  3416.         free (mode_string);
  3417.     }
  3418.  
  3419.     list = last = NULL;
  3420.     size = 0;
  3421.     if (sb.st_size > 0)
  3422.     {
  3423.         /* Throughout this section we use binary mode to read the
  3424.            file we are sending.  The client handles any line ending
  3425.            translation if necessary.  */
  3426.  
  3427.         if (gzip_level
  3428.         /*
  3429.          * For really tiny files, the gzip process startup
  3430.          * time will outweigh the compression savings.  This
  3431.          * might be computable somehow; using 100 here is just
  3432.          * a first approximation.
  3433.          */
  3434.         && sb.st_size > 100)
  3435.         {
  3436.         int status, fd, gzip_status;
  3437.         pid_t gzip_pid;
  3438.  
  3439.         fd = open (file, O_RDONLY | OPEN_BINARY, 0);
  3440.         if (fd < 0)
  3441.             error (1, errno, "reading %s", short_pathname);
  3442.         fd = filter_through_gzip (fd, 1, gzip_level, &gzip_pid);
  3443.         f = fdopen (fd, "rb");
  3444.         status = buf_read_file_to_eof (f, &list, &last);
  3445.         size = buf_chain_length (list);
  3446.         if (status == -2)
  3447.             (*protocol.memory_error) (&protocol);
  3448.         else if (status != 0)
  3449.             error (1, ferror (f) ? errno : 0, "reading %s",
  3450.                short_pathname);
  3451.         if (fclose (f) == EOF)
  3452.             error (1, errno, "reading %s", short_pathname);
  3453.         if (waitpid (gzip_pid, &gzip_status, 0) == -1)
  3454.             error (1, errno, "waiting for gzip process %ld",
  3455.                (long) gzip_pid);
  3456.         else if (gzip_status != 0)
  3457.             error (1, 0, "gzip exited %d", gzip_status);
  3458.         /* Prepending length with "z" is flag for using gzip here.  */
  3459.         buf_output0 (&protocol, "z");
  3460.         }
  3461.         else
  3462.         {
  3463.         long status;
  3464.  
  3465.         size = sb.st_size;
  3466.         f = fopen (file, "rb");
  3467.         if (f == NULL)
  3468.             error (1, errno, "reading %s", short_pathname);
  3469.         status = buf_read_file (f, sb.st_size, &list, &last);
  3470.         if (status == -2)
  3471.             (*protocol.memory_error) (&protocol);
  3472.         else if (status != 0)
  3473.             error (1, ferror (f) ? errno : 0, "reading %s",
  3474.                short_pathname);
  3475.         if (fclose (f) == EOF)
  3476.             error (1, errno, "reading %s", short_pathname);
  3477.         }
  3478.     }
  3479.  
  3480.     sprintf (size_text, "%lu\n", size);
  3481.     buf_output0 (&protocol, size_text);
  3482.  
  3483.     buf_append_data (&protocol, list, last);
  3484.     /* Note we only send a newline here if the file ended with one.  */
  3485.  
  3486.     /*
  3487.      * Avoid using up too much disk space for temporary files.
  3488.      * A file which does not exist indicates that the file is up-to-date,
  3489.      * which is now the case.  If this is SERVER_MERGED, the file is
  3490.      * not up-to-date, and we indicate that by leaving the file there.
  3491.      * I'm thinking of cases like "cvs update foo/foo.c foo".
  3492.      */
  3493.     if ((updated == SERVER_UPDATED || updated == SERVER_PATCHED)
  3494.         /* But if we are joining, we'll need the file when we call
  3495.            join_file.  */
  3496.         && !joining ())
  3497.         unlink (file);
  3498.     }
  3499.     else if (scratched_file != NULL && entries_line == NULL)
  3500.     {
  3501.     if (strcmp (scratched_file, file) != 0)
  3502.         error (1, 0,
  3503.            "CVS server internal error: `%s' vs. `%s' scratched",
  3504.            scratched_file,
  3505.            file);
  3506.     free (scratched_file);
  3507.     scratched_file = NULL;
  3508.  
  3509.     if (kill_scratched_file)
  3510.         buf_output0 (&protocol, "Removed ");
  3511.     else
  3512.         buf_output0 (&protocol, "Remove-entry ");
  3513.     output_dir (update_dir, repository);
  3514.     buf_output0 (&protocol, file);
  3515.     buf_output (&protocol, "\n", 1);
  3516.     }
  3517.     else if (scratched_file == NULL && entries_line == NULL)
  3518.     {
  3519.     /*
  3520.      * This can happen with death support if we were processing
  3521.      * a dead file in a checkout.
  3522.      */
  3523.     }
  3524.     else
  3525.     error (1, 0,
  3526.            "CVS server internal error: Register *and* Scratch_Entry.\n");
  3527.     buf_send_counted (&protocol);
  3528.   done:
  3529.     free (short_pathname);
  3530. }
  3531.  
  3532. void
  3533. server_set_entstat (update_dir, repository)
  3534.     char *update_dir;
  3535.     char *repository;
  3536. {
  3537.     static int set_static_supported = -1;
  3538.     if (set_static_supported == -1)
  3539.     set_static_supported = supported_response ("Set-static-directory");
  3540.     if (!set_static_supported) return;
  3541.  
  3542.     buf_output0 (&protocol, "Set-static-directory ");
  3543.     output_dir (update_dir, repository);
  3544.     buf_output0 (&protocol, "\n");
  3545.     buf_send_counted (&protocol);
  3546. }
  3547.  
  3548. void
  3549. server_clear_entstat (update_dir, repository)
  3550.      char *update_dir;
  3551.      char *repository;
  3552. {
  3553.     static int clear_static_supported = -1;
  3554.     if (clear_static_supported == -1)
  3555.     clear_static_supported = supported_response ("Clear-static-directory");
  3556.     if (!clear_static_supported) return;
  3557.  
  3558.     if (noexec)
  3559.     return;
  3560.  
  3561.     buf_output0 (&protocol, "Clear-static-directory ");
  3562.     output_dir (update_dir, repository);
  3563.     buf_output0 (&protocol, "\n");
  3564.     buf_send_counted (&protocol);
  3565. }
  3566.  
  3567. void
  3568. server_set_sticky (update_dir, repository, tag, date)
  3569.     char *update_dir;
  3570.     char *repository;
  3571.     char *tag;
  3572.     char *date;
  3573. {
  3574.     static int set_sticky_supported = -1;
  3575.     if (set_sticky_supported == -1)
  3576.     set_sticky_supported = supported_response ("Set-sticky");
  3577.     if (!set_sticky_supported) return;
  3578.  
  3579.     if (noexec)
  3580.     return;
  3581.  
  3582.     if (tag == NULL && date == NULL)
  3583.     {
  3584.     buf_output0 (&protocol, "Clear-sticky ");
  3585.     output_dir (update_dir, repository);
  3586.     buf_output0 (&protocol, "\n");
  3587.     }
  3588.     else
  3589.     {
  3590.     buf_output0 (&protocol, "Set-sticky ");
  3591.     output_dir (update_dir, repository);
  3592.     buf_output0 (&protocol, "\n");
  3593.     if (tag != NULL)
  3594.     {
  3595.         buf_output0 (&protocol, "T");
  3596.         buf_output0 (&protocol, tag);
  3597.     }
  3598.     else
  3599.     {
  3600.         buf_output0 (&protocol, "D");
  3601.         buf_output0 (&protocol, date);
  3602.     }
  3603.     buf_output0 (&protocol, "\n");
  3604.     }
  3605.     buf_send_counted (&protocol);
  3606. }
  3607.  
  3608. struct template_proc_data
  3609. {
  3610.     char *update_dir;
  3611.     char *repository;
  3612. };
  3613.  
  3614. /* Here as a static until we get around to fixing Parse_Info to pass along
  3615.    a void * for it.  */
  3616. static struct template_proc_data *tpd;
  3617.  
  3618. static int
  3619. template_proc (repository, template)
  3620.     char *repository;
  3621.     char *template;
  3622. {
  3623.     FILE *fp;
  3624.     char buf[1024];
  3625.     size_t n;
  3626.     struct stat sb;
  3627.     struct template_proc_data *data = tpd;
  3628.  
  3629.     if (!supported_response ("Template"))
  3630.     /* Might want to warn the user that the rcsinfo feature won't work.  */
  3631.     return 0;
  3632.     buf_output0 (&protocol, "Template ");
  3633.     output_dir (data->update_dir, data->repository);
  3634.     buf_output0 (&protocol, "\n");
  3635.  
  3636.     fp = fopen (template, "rb");
  3637.     if (fp == NULL)
  3638.     {
  3639.     error (0, errno, "Couldn't open rcsinfo template file %s", template);
  3640.     return 1;
  3641.     }
  3642.     if (fstat (fileno (fp), &sb) < 0)
  3643.     {
  3644.     error (0, errno, "cannot stat rcsinfo template file %s", template);
  3645.     return 1;
  3646.     }
  3647.     sprintf (buf, "%ld\n", (long) sb.st_size);
  3648.     buf_output0 (&protocol, buf);
  3649.     while (!feof (fp))
  3650.     {
  3651.     n = fread (buf, 1, sizeof buf, fp);
  3652.     buf_output (&protocol, buf, n);
  3653.     if (ferror (fp))
  3654.     {
  3655.         error (0, errno, "cannot read rcsinfo template file %s", template);
  3656.         (void) fclose (fp);
  3657.         return 1;
  3658.     }
  3659.     }
  3660.     if (fclose (fp) < 0)
  3661.     error (0, errno, "cannot close rcsinfo template file %s", template);
  3662.     return 0;
  3663. }
  3664.  
  3665. void
  3666. server_template (update_dir, repository)
  3667.     char *update_dir;
  3668.     char *repository;
  3669. {
  3670.     struct template_proc_data data;
  3671.     data.update_dir = update_dir;
  3672.     data.repository = repository;
  3673.     tpd = &data;
  3674.     (void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, 1);
  3675. }
  3676.  
  3677. static void
  3678. serve_gzip_contents (arg)
  3679.      char *arg;
  3680. {
  3681.     int level;
  3682.     level = atoi (arg);
  3683.     if (level == 0)
  3684.     level = 6;
  3685.     gzip_level = level;
  3686. }
  3687.  
  3688. static void
  3689. serve_ignore (arg)
  3690.     char *arg;
  3691. {
  3692.     /*
  3693.      * Just ignore this command.  This is used to support the
  3694.      * update-patches command, which is not a real command, but a signal
  3695.      * to the client that update will accept the -u argument.
  3696.      */
  3697. }
  3698.  
  3699. static int
  3700. expand_proc (pargc, argv, where, mwhere, mfile, shorten,
  3701.          local_specified, omodule, msg)
  3702.     int *pargc;
  3703.     char **argv;
  3704.     char *where;
  3705.     char *mwhere;
  3706.     char *mfile;
  3707.     int shorten;
  3708.     int local_specified;
  3709.     char *omodule;
  3710.     char *msg;
  3711. {
  3712.     int i;
  3713.     char *dir = argv[0];
  3714.  
  3715.     /* If mwhere has been specified, the thing we're expanding is a
  3716.        module -- just return its name so the client will ask for the
  3717.        right thing later.  If it is an alias or a real directory,
  3718.        mwhere will not be set, so send out the appropriate
  3719.        expansion. */
  3720.  
  3721.     if (mwhere != NULL)
  3722.     {
  3723.     printf ("Module-expansion %s", mwhere);
  3724.     if (mfile != NULL)
  3725.     {
  3726.         printf ("/%s", mfile);
  3727.     }
  3728.     printf ("\n");
  3729.     }
  3730.     else
  3731.       {
  3732.     /* We may not need to do this anymore -- check the definition
  3733.            of aliases before removing */
  3734.     if (*pargc == 1)
  3735.       printf ("Module-expansion %s\n", dir);
  3736.     else
  3737.       for (i = 1; i < *pargc; ++i)
  3738.         printf ("Module-expansion %s/%s\n", dir, argv[i]);
  3739.       }
  3740.     return 0;
  3741. }
  3742.  
  3743. static void
  3744. serve_expand_modules (arg)
  3745.     char *arg;
  3746. {
  3747.     int i;
  3748.     int err;
  3749.     DBM *db;
  3750.     err = 0;
  3751.  
  3752.     /*
  3753.      * FIXME: error handling is bogus; do_module can write to stdout and/or
  3754.      * stderr and we're not using do_cvs_command.
  3755.      */
  3756.  
  3757.     server_expanding = 1;
  3758.     db = open_module ();
  3759.     for (i = 1; i < argument_count; i++)
  3760.     err += do_module (db, argument_vector[i],
  3761.               CHECKOUT, "Updating", expand_proc,
  3762.               NULL, 0, 0, 0,
  3763.               (char *) NULL);
  3764.     close_module (db);
  3765.     server_expanding = 0;
  3766.     {
  3767.     /* argument_vector[0] is a dummy argument, we don't mess with it.  */
  3768.     char **cp;
  3769.     for (cp = argument_vector + 1;
  3770.          cp < argument_vector + argument_count;
  3771.          ++cp)
  3772.         free (*cp);
  3773.  
  3774.     argument_count = 1;
  3775.     }
  3776.     if (err)
  3777.     /* We will have printed an error message already.  */
  3778.     printf ("error  \n");
  3779.     else
  3780.     printf ("ok\n");
  3781. }
  3782.  
  3783. void
  3784. server_prog (dir, name, which)
  3785.     char *dir;
  3786.     char *name;
  3787.     enum progs which;
  3788. {
  3789.     if (!supported_response ("Set-checkin-prog"))
  3790.     {
  3791.     printf ("E \
  3792. warning: this client does not support -i or -u flags in the modules file.\n");
  3793.     return;
  3794.     }
  3795.     switch (which)
  3796.     {
  3797.     case PROG_CHECKIN:
  3798.         printf ("Set-checkin-prog ");
  3799.         break;
  3800.     case PROG_UPDATE:
  3801.         printf ("Set-update-prog ");
  3802.         break;
  3803.     }
  3804.     printf ("%s\n%s\n", dir, name);
  3805. }
  3806.  
  3807. static void
  3808. serve_checkin_prog (arg)
  3809.     char *arg;
  3810. {
  3811.     FILE *f;
  3812.     f = fopen (CVSADM_CIPROG, "w+");
  3813.     if (f == NULL)
  3814.     {
  3815.     pending_error = errno;
  3816.     pending_error_text = malloc (80 + strlen(CVSADM_CIPROG));
  3817.     sprintf(pending_error_text, "E cannot open %s", CVSADM_CIPROG);
  3818.     return;
  3819.     }
  3820.     if (fprintf (f, "%s\n", arg) < 0)
  3821.     {
  3822.     pending_error = errno;
  3823.     pending_error_text = malloc (80 + strlen(CVSADM_CIPROG));
  3824.     sprintf(pending_error_text, "E cannot write to %s", CVSADM_CIPROG);
  3825.     return;
  3826.     }
  3827.     if (fclose (f) == EOF)
  3828.     {
  3829.     pending_error = errno;
  3830.     pending_error_text = malloc (80 + strlen(CVSADM_CIPROG));
  3831.     sprintf(pending_error_text, "E cannot close %s", CVSADM_CIPROG);
  3832.     return;
  3833.     }
  3834. }
  3835.  
  3836. static void
  3837. serve_update_prog (arg)
  3838.     char *arg;
  3839. {
  3840.     FILE *f;
  3841.     f = fopen (CVSADM_UPROG, "w+");
  3842.     if (f == NULL)
  3843.     {
  3844.     pending_error = errno;
  3845.     pending_error_text = malloc (80 + strlen(CVSADM_UPROG));
  3846.     sprintf(pending_error_text, "E cannot open %s", CVSADM_UPROG);
  3847.     return;
  3848.     }
  3849.     if (fprintf (f, "%s\n", arg) < 0)
  3850.     {
  3851.     pending_error = errno;
  3852.     pending_error_text = malloc (80 + strlen(CVSADM_UPROG));
  3853.     sprintf(pending_error_text, "E cannot write to %s", CVSADM_UPROG);
  3854.     return;
  3855.     }
  3856.     if (fclose (f) == EOF)
  3857.     {
  3858.     pending_error = errno;
  3859.     pending_error_text = malloc (80 + strlen(CVSADM_UPROG));
  3860.     sprintf(pending_error_text, "E cannot close %s", CVSADM_UPROG);
  3861.     return;
  3862.     }
  3863. }
  3864.  
  3865. static void serve_valid_requests PROTO((char *arg));
  3866.  
  3867. #endif /* SERVER_SUPPORT */
  3868. #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
  3869.  
  3870. /*
  3871.  * Parts of this table are shared with the client code,
  3872.  * but the client doesn't need to know about the handler
  3873.  * functions.
  3874.  */
  3875.  
  3876. struct request requests[] =
  3877. {
  3878. #ifdef SERVER_SUPPORT
  3879. #define REQ_LINE(n, f, s) {n, f, s}
  3880. #else
  3881. #define REQ_LINE(n, f, s) {n, s}
  3882. #endif
  3883.  
  3884.   REQ_LINE("Root", serve_root, rq_essential),
  3885.   REQ_LINE("Valid-responses", serve_valid_responses, rq_essential),
  3886.   REQ_LINE("valid-requests", serve_valid_requests, rq_essential),
  3887.   REQ_LINE("Repository", serve_repository, rq_essential),
  3888.   REQ_LINE("Directory", serve_directory, rq_optional),
  3889.   REQ_LINE("Max-dotdot", serve_max_dotdot, rq_optional),
  3890.   REQ_LINE("Static-directory", serve_static_directory, rq_optional),
  3891.   REQ_LINE("Sticky", serve_sticky, rq_optional),
  3892.   REQ_LINE("Checkin-prog", serve_checkin_prog, rq_optional),
  3893.   REQ_LINE("Update-prog", serve_update_prog, rq_optional),
  3894.   REQ_LINE("Entry", serve_entry, rq_essential),
  3895.   REQ_LINE("Modified", serve_modified, rq_essential),
  3896.   REQ_LINE("Lost", serve_lost, rq_optional),
  3897.   REQ_LINE("UseUnchanged", serve_enable_unchanged, rq_enableme),
  3898.   REQ_LINE("Unchanged", serve_unchanged, rq_optional),
  3899.   REQ_LINE("Notify", serve_notify, rq_optional),
  3900.   REQ_LINE("Questionable", serve_questionable, rq_optional),
  3901.   REQ_LINE("Case", serve_case, rq_optional),
  3902.   REQ_LINE("Argument", serve_argument, rq_essential),
  3903.   REQ_LINE("Argumentx", serve_argumentx, rq_essential),
  3904.   REQ_LINE("Global_option", serve_global_option, rq_optional),
  3905.   REQ_LINE("Set", serve_set, rq_optional),
  3906.   REQ_LINE("expand-modules", serve_expand_modules, rq_optional),
  3907.   REQ_LINE("ci", serve_ci, rq_essential),
  3908.   REQ_LINE("co", serve_co, rq_essential),
  3909.   REQ_LINE("update", serve_update, rq_essential),
  3910.   REQ_LINE("diff", serve_diff, rq_optional),
  3911.   REQ_LINE("log", serve_log, rq_optional),
  3912.   REQ_LINE("add", serve_add, rq_optional),
  3913.   REQ_LINE("remove", serve_remove, rq_optional),
  3914.   REQ_LINE("update-patches", serve_ignore, rq_optional),
  3915.   REQ_LINE("gzip-file-contents", serve_gzip_contents, rq_optional),
  3916.   REQ_LINE("status", serve_status, rq_optional),
  3917.   REQ_LINE("rdiff", serve_rdiff, rq_optional),
  3918.   REQ_LINE("tag", serve_tag, rq_optional),
  3919.   REQ_LINE("rtag", serve_rtag, rq_optional),
  3920.   REQ_LINE("import", serve_import, rq_optional),
  3921.   REQ_LINE("admin", serve_admin, rq_optional),
  3922.   REQ_LINE("export", serve_export, rq_optional),
  3923.   REQ_LINE("history", serve_history, rq_optional),
  3924.   REQ_LINE("release", serve_release, rq_optional),
  3925.   REQ_LINE("watch-on", serve_watch_on, rq_optional),
  3926.   REQ_LINE("watch-off", serve_watch_off, rq_optional),
  3927.   REQ_LINE("watch-add", serve_watch_add, rq_optional),
  3928.   REQ_LINE("watch-remove", serve_watch_remove, rq_optional),
  3929.   REQ_LINE("watchers", serve_watchers, rq_optional),
  3930.   REQ_LINE("editors", serve_editors, rq_optional),
  3931.   REQ_LINE("init", serve_init, rq_optional),
  3932.   REQ_LINE("annotate", serve_annotate, rq_optional),
  3933.   REQ_LINE("noop", serve_noop, rq_optional),
  3934.   REQ_LINE(NULL, NULL, rq_optional)
  3935.  
  3936. #undef REQ_LINE
  3937. };
  3938.  
  3939. #endif /* SERVER_SUPPORT or CLIENT_SUPPORT */
  3940. #ifdef SERVER_SUPPORT
  3941.  
  3942. static void
  3943. serve_valid_requests (arg)
  3944.      char *arg;
  3945. {
  3946.     struct request *rq;
  3947.     if (print_pending_error ())
  3948.     return;
  3949.     printf ("Valid-requests");
  3950.     for (rq = requests; rq->name != NULL; rq++)
  3951.     if (rq->func != NULL)
  3952.         printf (" %s", rq->name);
  3953.     printf ("\nok\n");
  3954. }
  3955.  
  3956. #ifdef sun
  3957. /*
  3958.  * Delete temporary files.  SIG is the signal making this happen, or
  3959.  * 0 if not called as a result of a signal.
  3960.  */
  3961. static int command_pid_is_dead;
  3962. static void wait_sig (sig)
  3963.      int sig;
  3964. {
  3965.   int status;
  3966.   pid_t r = wait (&status);
  3967.   if (r == command_pid)
  3968.     command_pid_is_dead++;
  3969. }
  3970. #endif
  3971.  
  3972. void
  3973. server_cleanup (sig)
  3974.     int sig;
  3975. {
  3976.     /* Do "rm -rf" on the temp directory.  */
  3977.     int len;
  3978.     char *cmd;
  3979.     char *temp_dir;
  3980.  
  3981.     if (dont_delete_temp)
  3982.     return;
  3983.  
  3984.     /* What a bogus kludge.  This disgusting code makes all kinds of
  3985.        assumptions about SunOS, and is only for a bug in that system.
  3986.        So only enable it on Suns.  */
  3987. #ifdef sun
  3988.     if (command_pid > 0) {
  3989.       /* To avoid crashes on SunOS due to bugs in SunOS tmpfs
  3990.      triggered by the use of rename() in RCS, wait for the
  3991.      subprocess to die.  Unfortunately, this means draining output
  3992.      while waiting for it to unblock the signal we sent it.  Yuck!  */
  3993.       int status;
  3994.       pid_t r;
  3995.  
  3996.       signal (SIGCHLD, wait_sig);
  3997.       if (sig)
  3998.     /* Perhaps SIGTERM would be more correct.  But the child
  3999.        process will delay the SIGINT delivery until its own
  4000.        children have exited.  */
  4001.     kill (command_pid, SIGINT);
  4002.       /* The caller may also have sent a signal to command_pid, so
  4003.      always try waiting.  First, though, check and see if it's still
  4004.      there....  */
  4005.     do_waitpid:
  4006.       r = waitpid (command_pid, &status, WNOHANG);
  4007.       if (r == 0)
  4008.     ;
  4009.       else if (r == command_pid)
  4010.     command_pid_is_dead++;
  4011.       else if (r == -1)
  4012.     switch (errno) {
  4013.     case ECHILD:
  4014.       command_pid_is_dead++;
  4015.       break;
  4016.     case EINTR:
  4017.       goto do_waitpid;
  4018.     }
  4019.       else
  4020.     /* waitpid should always return one of the above values */
  4021.     abort ();
  4022.       while (!command_pid_is_dead) {
  4023.     struct timeval timeout;
  4024.     struct fd_set_wrapper readfds;
  4025.     char buf[100];
  4026.     int i;
  4027.  
  4028.     /* Use a non-zero timeout to avoid eating up CPU cycles.  */
  4029.     timeout.tv_sec = 2;
  4030.     timeout.tv_usec = 0;
  4031.     readfds = command_fds_to_drain;
  4032.     switch (select (max_command_fd + 1, &readfds.fds,
  4033.             (fd_set *)0, (fd_set *)0,
  4034.             &timeout)) {
  4035.     case -1:
  4036.       if (errno != EINTR)
  4037.         abort ();
  4038.     case 0:
  4039.       /* timeout */
  4040.       break;
  4041.     case 1:
  4042.       for (i = 0; i <= max_command_fd; i++)
  4043.         {
  4044.           if (!FD_ISSET (i, &readfds.fds))
  4045.         continue;
  4046.           /* this fd is non-blocking */
  4047.           while (read (i, buf, sizeof (buf)) >= 1)
  4048.         ;
  4049.         }
  4050.       break;
  4051.     default:
  4052.       abort ();
  4053.     }
  4054.       }
  4055.     }
  4056. #endif
  4057.  
  4058.     /* This might be set by the user in ~/.bashrc, ~/.cshrc, etc.  */
  4059.     temp_dir = getenv ("TMPDIR");
  4060.     if (temp_dir == NULL || temp_dir[0] == '\0')
  4061.         temp_dir = "/tmp";
  4062.     chdir(temp_dir);
  4063.  
  4064.     len = strlen (server_temp_dir) + 80;
  4065.     cmd = malloc (len);
  4066.     if (cmd == NULL)
  4067.     {
  4068.     printf ("E Cannot delete %s on server; out of memory\n",
  4069.         server_temp_dir);
  4070.     return;
  4071.     }
  4072.     sprintf (cmd, "rm -rf %s", server_temp_dir);
  4073.     system (cmd);
  4074.     free (cmd);
  4075. }
  4076.  
  4077. int server_active = 0;
  4078. int server_expanding = 0;
  4079.  
  4080. int
  4081. server (argc, argv)
  4082.      int argc;
  4083.      char **argv;
  4084. {
  4085.     if (argc == -1)
  4086.     {
  4087.     static const char *const msg[] =
  4088.     {
  4089.         "Usage: %s %s\n",
  4090.         "  Normally invoked by a cvs client on a remote machine.\n",
  4091.         NULL
  4092.     };
  4093.     usage (msg);
  4094.     }
  4095.     /* Ignore argc and argv.  They might be from .cvsrc.  */
  4096.  
  4097.     /* Since we're in the server parent process, error should use the
  4098.        protocol to report error messages.  */
  4099.     error_use_protocol = 1;
  4100.  
  4101.     /*
  4102.      * Put Rcsbin at the start of PATH, so that rcs programs can find
  4103.      * themselves.
  4104.      */
  4105. #ifdef HAVE_PUTENV
  4106.     if (Rcsbin != NULL && *Rcsbin)
  4107.     {
  4108.         char *p;
  4109.     char *env;
  4110.  
  4111.     p = getenv ("PATH");
  4112.     if (p != NULL)
  4113.     {
  4114.         env = malloc (strlen (Rcsbin) + strlen (p) + sizeof "PATH=:");
  4115.         if (env != NULL)
  4116.             sprintf (env, "PATH=%s:%s", Rcsbin, p);
  4117.     }
  4118.     else
  4119.     {
  4120.         env = malloc (strlen (Rcsbin) + sizeof "PATH=");
  4121.         if (env != NULL)
  4122.             sprintf (env, "PATH=%s", Rcsbin);
  4123.     }
  4124.     if (env == NULL)
  4125.     {
  4126.         printf ("E Fatal server error, aborting.\n\
  4127. error ENOMEM Virtual memory exhausted.\n");
  4128.         exit (EXIT_FAILURE);
  4129.     }
  4130.     putenv (env);
  4131.     }
  4132. #endif
  4133.  
  4134.     /* OK, now figure out where we stash our temporary files.  */
  4135.     {
  4136.     char *p;
  4137.  
  4138.     /* This might be set by the user in ~/.bashrc, ~/.cshrc, etc.  */
  4139.     char *temp_dir = getenv ("TMPDIR");
  4140.     if (temp_dir == NULL || temp_dir[0] == '\0')
  4141.         temp_dir = "/tmp";
  4142.  
  4143.     server_temp_dir = malloc (strlen (temp_dir) + 80);
  4144.     if (server_temp_dir == NULL)
  4145.     {
  4146.         /*
  4147.          * Strictly speaking, we're not supposed to output anything
  4148.          * now.  But we're about to exit(), give it a try.
  4149.          */
  4150.         printf ("E Fatal server error, aborting.\n\
  4151. error ENOMEM Virtual memory exhausted.\n");
  4152.         exit (EXIT_FAILURE);
  4153.     }
  4154.     strcpy (server_temp_dir, temp_dir);
  4155.  
  4156.     /* Remove a trailing slash from TMPDIR if present.  */
  4157.     p = server_temp_dir + strlen (server_temp_dir) - 1;
  4158.     if (*p == '/')
  4159.         *p = '\0';
  4160.  
  4161.     /*
  4162.      * I wanted to use cvs-serv/PID, but then you have to worry about
  4163.      * the permissions on the cvs-serv directory being right.  So
  4164.      * use cvs-servPID.
  4165.      */
  4166.     strcat (server_temp_dir, "/cvs-serv");
  4167.  
  4168.     p = server_temp_dir + strlen (server_temp_dir);
  4169.     sprintf (p, "%ld", (long) getpid ());
  4170.     }
  4171.  
  4172.     (void) SIG_register (SIGHUP, server_cleanup);
  4173.     (void) SIG_register (SIGINT, server_cleanup);
  4174.     (void) SIG_register (SIGQUIT, server_cleanup);
  4175.     (void) SIG_register (SIGPIPE, server_cleanup);
  4176.     (void) SIG_register (SIGTERM, server_cleanup);
  4177.     
  4178.     /* Now initialize our argument vector (for arguments from the client).  */
  4179.  
  4180.     /* Small for testing.  */
  4181.     argument_vector_size = 1;
  4182.     argument_vector =
  4183.     (char **) malloc (argument_vector_size * sizeof (char *));
  4184.     if (argument_vector == NULL)
  4185.     {
  4186.     /*
  4187.      * Strictly speaking, we're not supposed to output anything
  4188.      * now.  But we're about to exit(), give it a try.
  4189.      */
  4190.     printf ("E Fatal server error, aborting.\n\
  4191. error ENOMEM Virtual memory exhausted.\n");
  4192.     exit (EXIT_FAILURE);
  4193.     }
  4194.  
  4195.     argument_count = 1;
  4196.     argument_vector[0] = "Dummy argument 0";
  4197.  
  4198.     buf_to_net.data = buf_to_net.last = NULL;
  4199.     buf_to_net.fd = STDOUT_FILENO;
  4200.     buf_to_net.output = 1;
  4201.     buf_to_net.nonblocking = 0;
  4202.     buf_to_net.memory_error = outbuf_memory_error;
  4203.  
  4204.     server_active = 1;
  4205.  
  4206.     while (1)
  4207.     {
  4208.     char *cmd, *orig_cmd;
  4209.     struct request *rq;
  4210.     
  4211.     orig_cmd = cmd = read_line (stdin);
  4212.     if (cmd == NULL)
  4213.         break;
  4214.     if (cmd == NO_MEM_ERROR)
  4215.     {
  4216.         printf ("E Fatal server error, aborting.\n\
  4217. error ENOMEM Virtual memory exhausted.\n");
  4218.         break;
  4219.     }
  4220.     for (rq = requests; rq->name != NULL; ++rq)
  4221.         if (strncmp (cmd, rq->name, strlen (rq->name)) == 0)
  4222.         {
  4223.         int len = strlen (rq->name);
  4224.         if (cmd[len] == '\0')
  4225.             cmd += len;
  4226.         else if (cmd[len] == ' ')
  4227.             cmd += len + 1;
  4228.         else
  4229.             /*
  4230.              * The first len characters match, but it's a different
  4231.              * command.  e.g. the command is "cooperate" but we matched
  4232.              * "co".
  4233.              */
  4234.             continue;
  4235.         (*rq->func) (cmd);
  4236.         break;
  4237.         }
  4238.     if (rq->name == NULL)
  4239.     {
  4240.         if (!print_pending_error ())
  4241.         printf ("error  unrecognized request `%s'\n", cmd);
  4242.     }
  4243.     free (orig_cmd);
  4244.     }
  4245.     server_cleanup (0);
  4246.     return 0;
  4247. }
  4248.  
  4249.  
  4250. #ifdef AUTH_SERVER_SUPPORT
  4251.  
  4252. extern char *crypt PROTO((const char *, const char *));
  4253.  
  4254. /* This was test code, which we may need again. */
  4255. #if 0
  4256.   /* If we were invoked this way, then stdin comes from the
  4257.      client and stdout/stderr writes to it. */
  4258.   int c;
  4259.   while ((c = getc (stdin)) != EOF && c != '*')
  4260.     {
  4261.       printf ("%c", toupper (c));
  4262.       fflush (stdout);
  4263.     }
  4264.   exit (0);
  4265. #endif /* 1/0 */
  4266.  
  4267.  
  4268. /* 
  4269.  * 0 means no entry found for this user.
  4270.  * 1 means entry found and password matches.
  4271.  * 2 means entry found, but password does not match.
  4272.  */
  4273. int
  4274. check_repository_password (username, password, repository, host_user_ptr)
  4275.      char *username, *password, *repository, **host_user_ptr;
  4276. {
  4277.     int retval = 0;
  4278.     FILE *fp;
  4279.     char *filename;
  4280.     char *linebuf;
  4281.     int found_it = 0;
  4282.     int namelen;
  4283.  
  4284.     filename = xmalloc (strlen (repository)
  4285.             + 1
  4286.             + strlen ("CVSROOT")
  4287.             + 1
  4288.             + strlen ("passwd")
  4289.             + 1);
  4290.  
  4291.     strcpy (filename, repository);
  4292.     strcat (filename, "/CVSROOT");
  4293.     strcat (filename, "/passwd");
  4294.   
  4295.     fp = fopen (filename, "r");
  4296.     if (fp == NULL)
  4297.     {
  4298.     if (!existence_error (errno))
  4299.         error (0, errno, "cannot open %s", filename);
  4300.     return 0;
  4301.     }
  4302.  
  4303.     /* Look for a relevant line -- one with this user's name. */
  4304.     namelen = strlen (username);
  4305.     while (1)
  4306.     {
  4307.     linebuf = read_line(fp);
  4308.     if (linebuf == NULL)
  4309.         {
  4310.             free (linebuf);
  4311.         break;
  4312.         }
  4313.     if (linebuf == NO_MEM_ERROR)
  4314.     {
  4315.             error (0, errno, "out of memory");
  4316.         break;
  4317.     }
  4318.     if ((strncmp (linebuf, username, namelen) == 0)
  4319.         && (linebuf[namelen] == ':'))
  4320.         {
  4321.         found_it = 1;
  4322.         break;
  4323.         }
  4324.         free (linebuf);
  4325.         
  4326.     }
  4327.     if (ferror (fp))
  4328.     error (0, errno, "cannot read %s", filename);
  4329.     if (fclose (fp) < 0)
  4330.     error (0, errno, "cannot close %s", filename);
  4331.  
  4332.     /* If found_it != 0, then linebuf contains the information we need. */
  4333.     if (found_it)
  4334.     {
  4335.     char *found_password;
  4336.  
  4337.     strtok (linebuf, ":");
  4338.     found_password = strtok (NULL, ": \n");
  4339.     *host_user_ptr = strtok (NULL, ": \n");
  4340.     if (*host_user_ptr == NULL) *host_user_ptr = username;
  4341.     if (strcmp (found_password, crypt (password, found_password)) == 0)
  4342.         retval = 1;
  4343.     else
  4344.         retval = 2;
  4345.     }
  4346.     else
  4347.     {
  4348.     *host_user_ptr = NULL;
  4349.     retval = 0;
  4350.     }
  4351.  
  4352.     free (filename);
  4353.  
  4354.     return retval;
  4355. }
  4356.  
  4357.  
  4358. /* Return a hosting username if password matches, else NULL. */
  4359. char *
  4360. check_password (username, password, repository)
  4361.     char *username, *password, *repository;
  4362. {
  4363.     int rc;
  4364.     char *host_user;
  4365.  
  4366.     /* First we see if this user has a password in the CVS-specific
  4367.        password file.  If so, that's enough to authenticate with.  If
  4368.        not, we'll check /etc/passwd. */
  4369.  
  4370.     rc = check_repository_password (username, password, repository,
  4371.                     &host_user);
  4372.  
  4373.     if (rc == 1)
  4374.     return host_user;
  4375.     else if (rc == 2)
  4376.     return 0;
  4377.     else if (rc == 0)
  4378.     {
  4379.     /* No cvs password found, so try /etc/passwd. */
  4380.  
  4381.     struct passwd *pw;
  4382.     char *found_passwd;
  4383.  
  4384.     pw = getpwnam (username);
  4385.     if (pw == NULL)
  4386.         {
  4387.         printf ("E Fatal error, aborting.\n\
  4388. error 0 %s: no such user\n", username);
  4389.         exit (EXIT_FAILURE);
  4390.     }
  4391.     found_passwd = pw->pw_passwd;
  4392.  
  4393.     if (found_passwd && *found_passwd)
  4394.         return ((! strcmp (found_passwd, crypt (password, found_passwd)))
  4395.             ? username : NULL);
  4396.     else if (password && *password)
  4397.         return username;
  4398.     else
  4399.         return NULL;
  4400.     }
  4401.     else
  4402.     {
  4403.     /* Something strange happened.  We don't know what it was, but
  4404.        we certainly won't grant authorization. */
  4405.     return NULL;
  4406.     }
  4407. }
  4408.  
  4409.  
  4410. /* Read username and password from client (i.e., stdin).
  4411.    If correct, then switch to run as that user and send an ACK to the
  4412.    client via stdout, else send NACK and die. */
  4413. void
  4414. authenticate_connection ()
  4415. {
  4416.   char tmp[PATH_MAX];
  4417.   char repository[PATH_MAX];
  4418.   char username[PATH_MAX];
  4419.   char password[PATH_MAX];
  4420.   char *host_user;
  4421.   char *descrambled_password;
  4422.   struct passwd *pw;
  4423.   int verify_and_exit = 0;
  4424.  
  4425.   /* The Authentication Protocol.  Client sends:
  4426.    *
  4427.    *   BEGIN AUTH REQUEST\n
  4428.    *   <REPOSITORY>\n
  4429.    *   <USERNAME>\n
  4430.    *   <PASSWORD>\n
  4431.    *   END AUTH REQUEST\n
  4432.    *
  4433.    * Server uses above information to authenticate, then sends
  4434.    *
  4435.    *   I LOVE YOU\n
  4436.    *
  4437.    * if it grants access, else
  4438.    *
  4439.    *   I HATE YOU\n
  4440.    *
  4441.    * if it denies access (and it exits if denying).
  4442.    *
  4443.    * When the client is "cvs login", the user does not desire actual
  4444.    * repository access, but would like to confirm the password with
  4445.    * the server.  In this case, the start and stop strings are
  4446.    *
  4447.    *   BEGIN VERIFICATION REQUEST\n
  4448.    *
  4449.    *            and
  4450.    *
  4451.    *   END VERIFICATION REQUEST\n
  4452.    *
  4453.    * On a verification request, the server's responses are the same
  4454.    * (with the obvious semantics), but it exits immediately after
  4455.    * sending the response in both cases.
  4456.    *
  4457.    * Why is the repository sent?  Well, note that the actual
  4458.    * client/server protocol can't start up until authentication is
  4459.    * successful.  But in order to perform authentication, the server
  4460.    * needs to look up the password in the special CVS passwd file,
  4461.    * before trying /etc/passwd.  So the client transmits the
  4462.    * repository as part of the "authentication protocol".  The
  4463.    * repository will be redundantly retransmitted later, but that's no
  4464.    * big deal.
  4465.    */
  4466.  
  4467.   /* Since we're in the server parent process, error should use the
  4468.      protocol to report error messages.  */
  4469.   error_use_protocol = 1;
  4470.  
  4471.   /* Make sure the protocol starts off on the right foot... */
  4472.   fgets (tmp, PATH_MAX, stdin);
  4473.   if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
  4474.     verify_and_exit = 1;
  4475.   else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") != 0)
  4476.     error (1, 0, "bad auth protocol start: %s", tmp);
  4477.     
  4478.   /* Get the three important pieces of information in order. */
  4479.   fgets (repository, PATH_MAX, stdin);
  4480.   fgets (username, PATH_MAX, stdin);
  4481.   fgets (password, PATH_MAX, stdin);
  4482.  
  4483.   /* Make them pure. */ 
  4484.   strip_trailing_newlines (repository);
  4485.   strip_trailing_newlines (username);
  4486.   strip_trailing_newlines (password);
  4487.  
  4488.   /* ... and make sure the protocol ends on the right foot. */
  4489.   fgets (tmp, PATH_MAX, stdin);
  4490.   if (strcmp (tmp,
  4491.               verify_and_exit ?
  4492.               "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n")
  4493.            != 0)
  4494.     {
  4495.       error (1, 0, "bad auth protocol end: %s", tmp);
  4496.     }
  4497.  
  4498.   /* We need the real cleartext before we hash it. */
  4499.   descrambled_password = descramble (password);
  4500.   host_user = check_password (username, descrambled_password, repository);
  4501.   if (host_user)
  4502.     {
  4503.       printf ("I LOVE YOU\n");
  4504.       fflush (stdout);
  4505.       memset (descrambled_password, 0, strlen (descrambled_password));
  4506.       free (descrambled_password);
  4507.     }
  4508.   else
  4509.     {
  4510.       printf ("I HATE YOU\n");
  4511.       fflush (stdout);
  4512.       memset (descrambled_password, 0, strlen (descrambled_password));
  4513.       free (descrambled_password);
  4514.       exit (EXIT_FAILURE);
  4515.     }
  4516.   
  4517.   /* Don't go any farther if we're just responding to "cvs login". */
  4518.   if (verify_and_exit)
  4519.     exit (0);
  4520.  
  4521.   /* Switch to run as this user. */
  4522.   pw = getpwnam (host_user);
  4523.   if (pw == NULL)
  4524.     {
  4525.       error (1, 0,
  4526.              "fatal error, aborting.\nerror 0 %s: no such user\n",
  4527.              username);
  4528.     }
  4529.   
  4530. #if HAVE_INITGROUPS
  4531.   initgroups (pw->pw_name, pw->pw_gid);
  4532. #endif /* HAVE_INITGROUPS */
  4533.  
  4534.   setgid (pw->pw_gid);
  4535.   setuid (pw->pw_uid);
  4536.   /* Inhibit access by randoms.  Don't want people randomly
  4537.      changing our temporary tree before we check things in.  */
  4538.   umask (077);
  4539.   
  4540. #if HAVE_PUTENV
  4541.   /* Set LOGNAME and USER in the environment, in case they are
  4542.      already set to something else.  */
  4543.   {
  4544.     char *env;
  4545.     
  4546.     env = xmalloc (sizeof "LOGNAME=" + strlen (username));
  4547.     (void) sprintf (env, "LOGNAME=%s", username);
  4548.     (void) putenv (env);
  4549.     
  4550.     env = xmalloc (sizeof "USER=" + strlen (username));
  4551.     (void) sprintf (env, "USER=%s", username);
  4552.     (void) putenv (env);
  4553.   }
  4554. #endif /* HAVE_PUTENV */
  4555. }
  4556.  
  4557. #endif /* AUTH_SERVER_SUPPORT */
  4558.  
  4559.  
  4560. #endif /* SERVER_SUPPORT */
  4561.  
  4562. /* Output LEN bytes at STR.  If LEN is zero, then output up to (not including)
  4563.    the first '\0' byte.  Should not be called from the server parent process
  4564.    (yet at least, in the future it might be extended so that works).  */
  4565.  
  4566. void
  4567. cvs_output (str, len)
  4568.     char *str;
  4569.     size_t len;
  4570. {
  4571.     if (len == 0)
  4572.     len = strlen (str);
  4573.     if (error_use_protocol)
  4574.     /* Eventually we'll probably want to make it so this case works,
  4575.        but for now, callers who want to output something with
  4576.        error_use_protocol in effect can just printf the "M foo"
  4577.        themselves.  */
  4578.     abort ();
  4579. #ifdef SERVER_SUPPORT
  4580.     if (server_active)
  4581.     {
  4582.     buf_output (&saved_output, str, len);
  4583.     buf_copy_lines (&protocol, &saved_output, 'M');
  4584.     buf_send_counted (&protocol);
  4585.     }
  4586.     else
  4587. #endif
  4588.     {
  4589.     size_t written;
  4590.     size_t to_write = len;
  4591.     char *p = str;
  4592.  
  4593.     while (to_write > 0)
  4594.     {
  4595.         written = fwrite (str, 1, to_write, stdout);
  4596.         if (written == 0)
  4597.         break;
  4598.         p += written;
  4599.         to_write -= written;
  4600.     }
  4601.     }
  4602. }
  4603.  
  4604. /* Like CVS_OUTPUT but output is for stderr not stdout.  */
  4605.  
  4606. void
  4607. cvs_outerr (str, len)
  4608.     char *str;
  4609.     size_t len;
  4610. {
  4611.     if (len == 0)
  4612.     len = strlen (str);
  4613.     if (error_use_protocol)
  4614.     /* Eventually we'll probably want to make it so this case works,
  4615.        but for now, callers who want to output something with
  4616.        error_use_protocol in effect can just printf the "E foo"
  4617.        themselves.  */
  4618.     abort ();
  4619. #ifdef SERVER_SUPPORT
  4620.     if (server_active)
  4621.     {
  4622.     buf_output (&saved_outerr, str, len);
  4623.     buf_copy_lines (&protocol, &saved_outerr, 'E');
  4624.     buf_send_counted (&protocol);
  4625.     }
  4626.     else
  4627. #endif
  4628.     {
  4629.     size_t written;
  4630.     size_t to_write = len;
  4631.     char *p = str;
  4632.  
  4633.     while (to_write > 0)
  4634.     {
  4635.         written = fwrite (str, 1, to_write, stderr);
  4636.         if (written == 0)
  4637.         break;
  4638.         p += written;
  4639.         to_write -= written;
  4640.     }
  4641.     }
  4642. }
  4643.